js: support JS interfaces (#12426)
parent
015cfdb49f
commit
a4c57ba56e
|
@ -147,7 +147,7 @@ pub fn (a array) repeat(count int) array {
|
|||
}
|
||||
}
|
||||
|
||||
#function makeEmptyArray() { return new array(new array_buffer({})); }
|
||||
#function makeEmptyArray() { return new array(new array_buffer({ arr: [], len: new int(0), index_start: new int(0), cap: new int(0) })); }
|
||||
#function makeEmtpyJSArray() { return new Array(); }
|
||||
|
||||
fn JS.makeEmptyArray() array
|
||||
|
|
|
@ -104,66 +104,3 @@ pub fn (f float_literal) str() string {
|
|||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn tof64(n JS.Number) f64 {
|
||||
res := f64(0.0)
|
||||
#res.val = n;
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn tof32(n JS.Number) f32 {
|
||||
res := f32(0.0)
|
||||
#res.val = n;
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn toi(n JS.Number) int {
|
||||
res := int(0)
|
||||
#res.val = Math.floor(n);
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn f64tonum(n f64) JS.Number {
|
||||
mut res := JS.Number{}
|
||||
#res = n.val;
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn itonum(n int) JS.Number {
|
||||
mut res := JS.Number{}
|
||||
#res = n.val;
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn i64tobigint(n i64) JS.BigInt {
|
||||
mut res := JS.BigInt{}
|
||||
#res = n.val;
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn u64tobigint(n u64) JS.BigInt {
|
||||
mut res := JS.BigInt{}
|
||||
#res = n.val;
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn tobool(b JS.Boolean) bool {
|
||||
res := false
|
||||
#res.val = b;
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn booltojs(b bool) JS.Boolean {
|
||||
mut res := JS.Boolean{}
|
||||
#res = b.val;
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -7,21 +7,62 @@
|
|||
|
||||
module builtin
|
||||
|
||||
pub struct JS.BigInt {}
|
||||
pub interface JS.Object {}
|
||||
|
||||
pub struct JS.Number {}
|
||||
pub interface JS.BigInt {
|
||||
JS.Any
|
||||
}
|
||||
|
||||
pub struct JS.String {
|
||||
pub interface JS.Number {
|
||||
JS.Any
|
||||
}
|
||||
|
||||
pub interface JS.String {
|
||||
JS.Any
|
||||
length JS.Number
|
||||
charAt(index JS.Number) JS.String
|
||||
charCodeAt(index JS.Number) JS.Number
|
||||
toUpperCase() JS.String
|
||||
toLowerCase() JS.String
|
||||
concat(a JS.String) JS.String
|
||||
includes(substr JS.String) JS.Boolean
|
||||
endsWith(substr JS.String) JS.Boolean
|
||||
startsWith(substr JS.String) JS.Boolean
|
||||
slice(a JS.Number, b JS.Number) JS.String
|
||||
split(dot JS.String) JS.Array
|
||||
indexOf(needle JS.String) JS.Number
|
||||
lastIndexOf(needle JS.String) JS.Number
|
||||
}
|
||||
|
||||
pub interface JS.Boolean {
|
||||
JS.Any
|
||||
}
|
||||
|
||||
pub interface JS.Map {
|
||||
JS.Any
|
||||
size JS.Number
|
||||
clear()
|
||||
delete(key JS.Any) JS.Boolean
|
||||
get(key JS.Any) JS.Any
|
||||
has(key JS.Any) JS.Any
|
||||
set(key JS.Any, val JS.Any)
|
||||
}
|
||||
|
||||
#function Any(val) { return val; }
|
||||
|
||||
pub interface JS.Any {}
|
||||
|
||||
pub interface JS.Array {
|
||||
JS.Any // map(fn (JS.Any) JS.Any) JS.Array
|
||||
map(JS.Any) JS.Array
|
||||
push(JS.Any) JS.Any
|
||||
pop() JS.Any
|
||||
at(JS.Number) JS.Any
|
||||
mut:
|
||||
length JS.Number
|
||||
}
|
||||
|
||||
pub struct JS.Boolean {}
|
||||
|
||||
pub struct JS.Array {
|
||||
length JS.Number
|
||||
}
|
||||
|
||||
pub struct JS.Map {}
|
||||
pub fn JS.Array.prototype.constructor(...any) JS.Array
|
||||
|
||||
// browser: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Error
|
||||
// node: https://nodejs.org/api/errors.html#errors_class_error
|
||||
|
@ -110,18 +151,3 @@ fn JS.Math.tan(f64) f64
|
|||
// JSON
|
||||
fn JS.JSON.stringify(any) string
|
||||
fn JS.JSON.parse(string) any
|
||||
|
||||
// String
|
||||
fn (v JS.String) slice(a int, b int) JS.String
|
||||
fn (v JS.String) split(dot JS.String) []JS.String
|
||||
fn (s JS.String) indexOf(needle JS.String) int
|
||||
fn (s JS.String) lastIndexOf(needle JS.String) int
|
||||
|
||||
fn (s JS.String) charAt(i int) JS.String
|
||||
fn (s JS.String) charCodeAt(i int) byte
|
||||
fn (s JS.String) toUpperCase() JS.String
|
||||
fn (s JS.String) toLowerCase() JS.String
|
||||
fn (s JS.String) concat(a JS.String) JS.String
|
||||
fn (s JS.String) includes(substr JS.String) bool
|
||||
fn (s JS.String) endsWith(substr JS.String) bool
|
||||
fn (s JS.String) startsWith(substr JS.String) bool
|
||||
|
|
|
@ -25,7 +25,7 @@ pub fn (s string) substr(start int, end int) string {
|
|||
}
|
||||
|
||||
pub fn (s string) after(dot string) string {
|
||||
return string(s.str.slice(s.str.lastIndexOf(dot.str) + 1, int(s.str.length)))
|
||||
return string(s.str.slice(JS.Number(int(s.str.lastIndexOf(dot.str)) + 1), s.str.length))
|
||||
}
|
||||
|
||||
pub fn (s string) after_char(dot byte) string {
|
||||
|
@ -34,7 +34,7 @@ pub fn (s string) after_char(dot byte) string {
|
|||
}
|
||||
|
||||
pub fn (s string) all_after(dot string) string {
|
||||
pos := if dot.len == 0 { -1 } else { s.str.indexOf(dot.str) }
|
||||
pos := if dot.len == 0 { -1 } else { int(s.str.indexOf(dot.str)) }
|
||||
if pos == -1 {
|
||||
return s.clone()
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ pub fn (s string) all_after(dot string) string {
|
|||
|
||||
// why does this exist?
|
||||
pub fn (s string) all_after_last(dot string) string {
|
||||
pos := if dot.len == 0 { -1 } else { s.str.lastIndexOf(dot.str) }
|
||||
pos := if dot.len == 0 { -1 } else { int(s.str.lastIndexOf(dot.str)) }
|
||||
if pos == -1 {
|
||||
return s.clone()
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ pub fn (s string) all_after_last(dot string) string {
|
|||
}
|
||||
|
||||
pub fn (s string) all_before(dot string) string {
|
||||
pos := if dot.len == 0 { -1 } else { s.str.indexOf(dot.str) }
|
||||
pos := if dot.len == 0 { -1 } else { int(s.str.indexOf(dot.str)) }
|
||||
if pos == -1 {
|
||||
return s.clone()
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ pub fn (s string) all_before(dot string) string {
|
|||
}
|
||||
|
||||
pub fn (s string) all_before_last(dot string) string {
|
||||
pos := if dot.len == 0 { -1 } else { s.str.lastIndexOf(dot.str) }
|
||||
pos := if dot.len == 0 { -1 } else { int(s.str.lastIndexOf(dot.str)) }
|
||||
if pos == -1 {
|
||||
return s.clone()
|
||||
}
|
||||
|
@ -72,16 +72,27 @@ pub fn (s string) bool() bool {
|
|||
}
|
||||
|
||||
pub fn (s string) split(dot string) []string {
|
||||
mut arr := s.str.split(dot.str).map(string(it))
|
||||
#arr = new array(new array_buffer({arr,index_start: new int(0),len: new int(arr.length)}))
|
||||
tmparr := s.str.split(dot.str).map(fn (it JS.Any) JS.Any {
|
||||
res := ''
|
||||
#res.str = it
|
||||
|
||||
return res
|
||||
})
|
||||
_ := tmparr
|
||||
mut arr := []string{}
|
||||
#arr = new array(new array_buffer({arr: tmparr,index_start: new int(0),len: new int(tmparr.length)}))
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
pub fn (s string) bytes() []byte {
|
||||
sep := ''
|
||||
mut arr := s.str.split(sep.str).map(it.charCodeAt(0))
|
||||
#arr = new array(new array_buffer({arr,index_start: new int(0),len: new int(arr.length)}))
|
||||
tmparr := s.str.split(sep.str).map(fn (it JS.Any) JS.Any {
|
||||
return JS.Any(byte(JS.String(it).charCodeAt(0)))
|
||||
})
|
||||
_ := tmparr
|
||||
mut arr := []byte{}
|
||||
#arr = new array(new array_buffer({arr: tmparr,index_start: new int(0),len: new int(tmparr.length)}))
|
||||
|
||||
return arr
|
||||
}
|
||||
|
@ -96,13 +107,14 @@ pub fn (s string) clone() string {
|
|||
}
|
||||
|
||||
pub fn (s string) contains(substr string) bool {
|
||||
return s.str.includes(substr.str)
|
||||
return bool(s.str.includes(substr.str))
|
||||
}
|
||||
|
||||
pub fn (s string) contains_any(chars string) bool {
|
||||
sep := ''
|
||||
for x in chars.str.split(sep.str) {
|
||||
if s.str.includes(x) {
|
||||
res := chars.str.split(sep.str)
|
||||
for i in 0 .. int(res.length) {
|
||||
if bool(s.str.includes(JS.String(res.at(JS.Number(i))))) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +126,7 @@ pub fn (s string) contains_any_substr(chars []string) bool {
|
|||
return true
|
||||
}
|
||||
for x in chars {
|
||||
if s.str.includes(x.str) {
|
||||
if bool(s.str.includes(x.str)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +136,12 @@ pub fn (s string) contains_any_substr(chars []string) bool {
|
|||
pub fn (s string) count(substr string) int {
|
||||
// TODO: "error: `[]JS.String` is not a struct" when returning arr.length or arr.len
|
||||
arr := s.str.split(substr.str)
|
||||
return native_str_arr_len(arr)
|
||||
len := int(arr.length)
|
||||
if len == 0 {
|
||||
return 0
|
||||
} else {
|
||||
return len - 1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (s string) ends_with(p string) bool {
|
||||
|
@ -135,7 +152,7 @@ pub fn (s string) ends_with(p string) bool {
|
|||
}
|
||||
|
||||
pub fn (s string) starts_with(p string) bool {
|
||||
return s.str.startsWith(p.str)
|
||||
return bool(s.str.startsWith(p.str))
|
||||
}
|
||||
|
||||
pub fn (s string) fields() []string {
|
||||
|
@ -170,7 +187,7 @@ pub fn (s string) fields() []string {
|
|||
}
|
||||
|
||||
pub fn (s string) find_between(start string, end string) string {
|
||||
return string(s.str.slice(s.str.indexOf(start.str) + 1, s.str.indexOf(end.str)))
|
||||
return string(s.str.slice(JS.Number(int(s.str.indexOf(start.str)) + 1), s.str.indexOf(end.str)))
|
||||
}
|
||||
|
||||
// unnecessary in the JS backend, implemented for api parity.
|
||||
|
|
|
@ -1,37 +1,36 @@
|
|||
module jsdom
|
||||
|
||||
pub struct JS.DOMMatrix {
|
||||
pub:
|
||||
is_2d JS.Boolean [noinit]
|
||||
is_identity JS.Boolean [noinit]
|
||||
pub mut:
|
||||
m11 JS.Number [noinit]
|
||||
m12 JS.Number [noinit]
|
||||
m13 JS.Number [noinit]
|
||||
m14 JS.Number [noinit]
|
||||
m21 JS.Number [noinit]
|
||||
m22 JS.Number [noinit]
|
||||
m23 JS.Number [noinit]
|
||||
m24 JS.Number [noinit]
|
||||
m31 JS.Number [noinit]
|
||||
m32 JS.Number [noinit]
|
||||
m33 JS.Number [noinit]
|
||||
m34 JS.Number [noinit]
|
||||
m41 JS.Number [noinit]
|
||||
m42 JS.Number [noinit]
|
||||
m43 JS.Number [noinit]
|
||||
m44 JS.Number [noinit]
|
||||
a JS.Number [noinit]
|
||||
b JS.Number [noinit]
|
||||
c JS.Number [noinit]
|
||||
d JS.Number [noinit]
|
||||
e JS.Number [noinit]
|
||||
f JS.Number [noinit]
|
||||
pub interface JS.DOMMatrix {
|
||||
is_2d JS.Boolean
|
||||
is_identity JS.Boolean
|
||||
mut:
|
||||
m11 JS.Number
|
||||
m12 JS.Number
|
||||
m13 JS.Number
|
||||
m14 JS.Number
|
||||
m21 JS.Number
|
||||
m22 JS.Number
|
||||
m23 JS.Number
|
||||
m24 JS.Number
|
||||
m31 JS.Number
|
||||
m32 JS.Number
|
||||
m33 JS.Number
|
||||
m34 JS.Number
|
||||
m41 JS.Number
|
||||
m42 JS.Number
|
||||
m43 JS.Number
|
||||
m44 JS.Number
|
||||
a JS.Number
|
||||
b JS.Number
|
||||
c JS.Number
|
||||
d JS.Number
|
||||
e JS.Number
|
||||
f JS.Number
|
||||
}
|
||||
|
||||
pub struct DOMMatrix {
|
||||
mut:
|
||||
matrix JS.DOMMatrix [noinit]
|
||||
matrix JS.DOMMatrix = JS.DOMMatrix(voidptr(0))
|
||||
}
|
||||
|
||||
pub fn (matrix DOMMatrix) str() string {
|
||||
|
@ -48,7 +47,7 @@ pub fn new_matrix(init []f64) DOMMatrix {
|
|||
_ := val
|
||||
#tmp.push(val);
|
||||
}
|
||||
mut m := JS.DOMMatrix{}
|
||||
mut m := JS.DOMMatrix(voidptr(0))
|
||||
#m = new DOMMatrix(tmp);
|
||||
|
||||
return DOMMatrix{m}
|
||||
|
@ -190,177 +189,177 @@ pub fn (m DOMMatrix) is_2d() bool {
|
|||
}
|
||||
|
||||
pub fn (m DOMMatrix) a() f64 {
|
||||
return tof64(m.matrix.a)
|
||||
return f64(m.matrix.a)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) b() f64 {
|
||||
return tof64(m.matrix.b)
|
||||
return f64(m.matrix.b)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) c() f64 {
|
||||
return tof64(m.matrix.c)
|
||||
return f64(m.matrix.c)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) d() f64 {
|
||||
return tof64(m.matrix.d)
|
||||
return f64(m.matrix.d)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) e() f64 {
|
||||
return tof64(m.matrix.e)
|
||||
return f64(m.matrix.e)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) f() f64 {
|
||||
return tof64(m.matrix.f)
|
||||
return f64(m.matrix.f)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_a(a f64) {
|
||||
m.matrix.a = f64tonum(a)
|
||||
m.matrix.a = JS.Number(a)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_b(b f64) {
|
||||
m.matrix.b = f64tonum(b)
|
||||
m.matrix.b = JS.Number(b)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_c(c f64) {
|
||||
m.matrix.c = f64tonum(c)
|
||||
m.matrix.c = JS.Number(c)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_d(d f64) {
|
||||
m.matrix.d = f64tonum(d)
|
||||
m.matrix.d = JS.Number(d)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_e(e f64) {
|
||||
m.matrix.e = f64tonum(e)
|
||||
m.matrix.e = JS.Number(e)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_f(f f64) {
|
||||
m.matrix.f = f64tonum(f)
|
||||
m.matrix.f = JS.Number(f)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m11() f64 {
|
||||
return tof64(m.matrix.m11)
|
||||
return f64(m.matrix.m11)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m12() f64 {
|
||||
return tof64(m.matrix.m12)
|
||||
return f64(m.matrix.m12)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m13() f64 {
|
||||
return tof64(m.matrix.m13)
|
||||
return f64(m.matrix.m13)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m14() f64 {
|
||||
return tof64(m.matrix.m14)
|
||||
return f64(m.matrix.m14)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m21() f64 {
|
||||
return tof64(m.matrix.m21)
|
||||
return f64(m.matrix.m21)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m22() f64 {
|
||||
return tof64(m.matrix.m22)
|
||||
return f64(m.matrix.m22)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m23() f64 {
|
||||
return tof64(m.matrix.m23)
|
||||
return f64(m.matrix.m23)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m24() f64 {
|
||||
return tof64(m.matrix.m24)
|
||||
return f64(m.matrix.m24)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m31() f64 {
|
||||
return tof64(m.matrix.m31)
|
||||
return f64(m.matrix.m31)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m32() f64 {
|
||||
return tof64(m.matrix.m32)
|
||||
return f64(m.matrix.m32)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m33() f64 {
|
||||
return tof64(m.matrix.m33)
|
||||
return f64(m.matrix.m33)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m34() f64 {
|
||||
return tof64(m.matrix.m34)
|
||||
return f64(m.matrix.m34)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m41() f64 {
|
||||
return tof64(m.matrix.m41)
|
||||
return f64(m.matrix.m41)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m42() f64 {
|
||||
return tof64(m.matrix.m42)
|
||||
return f64(m.matrix.m42)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m43() f64 {
|
||||
return tof64(m.matrix.m43)
|
||||
return f64(m.matrix.m43)
|
||||
}
|
||||
|
||||
pub fn (m DOMMatrix) m44() f64 {
|
||||
return tof64(m.matrix.m44)
|
||||
return f64(m.matrix.m44)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m11(x f64) {
|
||||
m.matrix.m11 = f64tonum(x)
|
||||
m.matrix.m11 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m12(x f64) {
|
||||
m.matrix.m12 = f64tonum(x)
|
||||
m.matrix.m12 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m13(x f64) {
|
||||
m.matrix.m13 = f64tonum(x)
|
||||
m.matrix.m13 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m14(x f64) {
|
||||
m.matrix.m14 = f64tonum(x)
|
||||
m.matrix.m14 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m21(x f64) {
|
||||
m.matrix.m21 = f64tonum(x)
|
||||
m.matrix.m21 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m22(x f64) {
|
||||
m.matrix.m22 = f64tonum(x)
|
||||
m.matrix.m22 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m23(x f64) {
|
||||
m.matrix.m23 = f64tonum(x)
|
||||
m.matrix.m23 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m24(x f64) {
|
||||
m.matrix.m24 = f64tonum(x)
|
||||
m.matrix.m24 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m31(x f64) {
|
||||
m.matrix.m31 = f64tonum(x)
|
||||
m.matrix.m31 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m32(x f64) {
|
||||
m.matrix.m32 = f64tonum(x)
|
||||
m.matrix.m32 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m33(x f64) {
|
||||
m.matrix.m33 = f64tonum(x)
|
||||
m.matrix.m33 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m34(x f64) {
|
||||
m.matrix.m34 = f64tonum(x)
|
||||
m.matrix.m34 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m41(x f64) {
|
||||
m.matrix.m41 = f64tonum(x)
|
||||
m.matrix.m41 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m42(x f64) {
|
||||
m.matrix.m42 = f64tonum(x)
|
||||
m.matrix.m42 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m43(x f64) {
|
||||
m.matrix.m43 = f64tonum(x)
|
||||
m.matrix.m43 = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut m DOMMatrix) set_m44(x f64) {
|
||||
m.matrix.m44 = f64tonum(x)
|
||||
m.matrix.m44 = JS.Number(x)
|
||||
}
|
||||
|
|
|
@ -51,11 +51,11 @@ pub fn (path Path2D) rect(x f64, y f64, width f64, height f64) {
|
|||
}
|
||||
|
||||
pub fn (path Path2D) line_to(x f64, y f64) {
|
||||
path.path.lineTo(f64tonum(x), f64tonum(y))
|
||||
path.path.lineTo(JS.Number(x), JS.Number(y))
|
||||
}
|
||||
|
||||
pub fn (path Path2D) move_to(x f64, y f64) {
|
||||
path.path.lineTo(f64tonum(x), f64tonum(y))
|
||||
path.path.lineTo(JS.Number(x), JS.Number(y))
|
||||
}
|
||||
|
||||
pub fn (path Path2D) close_path() {
|
||||
|
|
|
@ -16,44 +16,44 @@ mut:
|
|||
pub fn new_dompoint(x f64, y f64, z f64, w f64) DOMPoint {
|
||||
mut point := DOMPoint{}
|
||||
|
||||
point.point.x = f64tonum(x)
|
||||
point.point.y = f64tonum(y)
|
||||
point.point.z = f64tonum(z)
|
||||
point.point.w = f64tonum(w)
|
||||
point.point.x = JS.Number(x)
|
||||
point.point.y = JS.Number(y)
|
||||
point.point.z = JS.Number(z)
|
||||
point.point.w = JS.Number(w)
|
||||
|
||||
return point
|
||||
}
|
||||
|
||||
pub fn (p DOMPoint) x() f64 {
|
||||
return tof64(p.point.x)
|
||||
return f64(p.point.x)
|
||||
}
|
||||
|
||||
pub fn (p DOMPoint) y() f64 {
|
||||
return tof64(p.point.y)
|
||||
return f64(p.point.y)
|
||||
}
|
||||
|
||||
pub fn (p DOMPoint) z() f64 {
|
||||
return tof64(p.point.z)
|
||||
return f64(p.point.z)
|
||||
}
|
||||
|
||||
pub fn (p DOMPoint) w() f64 {
|
||||
return tof64(p.point.w)
|
||||
return f64(p.point.w)
|
||||
}
|
||||
|
||||
pub fn (mut p DOMPoint) set_x(x f64) {
|
||||
p.point.x = f64tonum(x)
|
||||
p.point.x = JS.Number(x)
|
||||
}
|
||||
|
||||
pub fn (mut p DOMPoint) set_y(y f64) {
|
||||
p.point.y = f64tonum(y)
|
||||
p.point.y = JS.Number(y)
|
||||
}
|
||||
|
||||
pub fn (mut p DOMPoint) set_z(z f64) {
|
||||
p.point.z = f64tonum(z)
|
||||
p.point.z = JS.Number(z)
|
||||
}
|
||||
|
||||
pub fn (mut p DOMPoint) set_w(w f64) {
|
||||
p.point.w = f64tonum(w)
|
||||
p.point.w = JS.Number(w)
|
||||
}
|
||||
|
||||
pub fn (p DOMPoint) matrix_transform(matrix DOMMatrix) DOMPoint {
|
||||
|
|
|
@ -458,6 +458,7 @@ pub fn (mut c Checker) expand_iface_embeds(idecl &ast.InterfaceDecl, level int,
|
|||
pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
||||
c.check_valid_pascal_case(node.name, 'interface name', node.pos)
|
||||
mut decl_sym := c.table.get_type_symbol(node.typ)
|
||||
is_js := node.language == .js
|
||||
if mut decl_sym.info is ast.Interface {
|
||||
if node.ifaces.len > 0 {
|
||||
all_ifaces := c.expand_iface_embeds(node, 0, node.ifaces)
|
||||
|
@ -552,8 +553,26 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
|||
c.check_valid_snake_case(method.name, 'method name', method.pos)
|
||||
}
|
||||
c.ensure_type_exists(method.return_type, method.return_type_pos) or { return }
|
||||
for param in method.params {
|
||||
if is_js {
|
||||
mtyp := c.table.get_type_symbol(method.return_type)
|
||||
if (mtyp.language != .js && !method.return_type.is_void())
|
||||
&& !mtyp.name.starts_with('JS.') {
|
||||
c.error('method $method.name returns non JS type', method.pos)
|
||||
}
|
||||
}
|
||||
for j, param in method.params {
|
||||
if j == 0 && is_js {
|
||||
continue // no need to check first param
|
||||
}
|
||||
c.ensure_type_exists(param.typ, param.pos) or { return }
|
||||
if is_js {
|
||||
ptyp := c.table.get_type_symbol(param.typ)
|
||||
if ptyp.kind != .function && ptyp.language != .js
|
||||
&& !ptyp.name.starts_with('JS.') {
|
||||
c.error('method `$method.name` accepts non JS type as parameter',
|
||||
method.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
for field in node.fields {
|
||||
field_sym := c.table.get_type_symbol(field.typ)
|
||||
|
@ -573,6 +592,12 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
|||
c.check_valid_snake_case(field.name, 'field name', field.pos)
|
||||
}
|
||||
c.ensure_type_exists(field.typ, field.pos) or { return }
|
||||
if is_js {
|
||||
tsym := c.table.get_type_symbol(field.typ)
|
||||
if tsym.language != .js && !tsym.name.starts_with('JS.') {
|
||||
c.error('field `$field.name` uses non JS type', field.pos)
|
||||
}
|
||||
}
|
||||
if field.typ == node.typ {
|
||||
c.error('recursive interface fields are not allowed because they cannot be initialised',
|
||||
field.type_pos)
|
||||
|
@ -1916,7 +1941,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||
}
|
||||
node.left_type = left_type
|
||||
// Set default values for .return_type & .receiver_type too,
|
||||
// or there will be hard to diagnose 0 type panics in cgen.
|
||||
// or there will be hard tRo diagnose 0 type panics in cgen.
|
||||
node.return_type = left_type
|
||||
node.receiver_type = left_type
|
||||
|
||||
|
@ -3067,6 +3092,11 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
|
|||
utyp := c.unwrap_generic(typ)
|
||||
typ_sym := c.table.get_type_symbol(utyp)
|
||||
mut inter_sym := c.table.get_type_symbol(interface_type)
|
||||
|
||||
// small hack for JS.Any type. Since `any` in regular V is getting deprecated we have our own JS.Any type for JS backend.
|
||||
if typ_sym.name == 'JS.Any' {
|
||||
return true
|
||||
}
|
||||
if mut inter_sym.info is ast.Interface {
|
||||
mut generic_type := interface_type
|
||||
mut generic_info := inter_sym.info
|
||||
|
@ -3105,7 +3135,8 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
|
|||
// `none` "implements" the Error interface
|
||||
return true
|
||||
}
|
||||
if typ_sym.kind == .interface_ && inter_sym.kind == .interface_ {
|
||||
if typ_sym.kind == .interface_ && inter_sym.kind == .interface_ && styp != 'JS.Any'
|
||||
&& inter_sym.name != 'JS.Any' {
|
||||
c.error('cannot implement interface `$inter_sym.name` with a different interface `$styp`',
|
||||
pos)
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ fn (mut g JsGen) to_js_typ_val(t ast.Type) string {
|
|||
styp = 'new map(new Map())'
|
||||
}
|
||||
.array {
|
||||
styp = '$prefix${g.sym_to_js_typ(sym)}()'
|
||||
styp = 'empty_array()'
|
||||
}
|
||||
.struct_ {
|
||||
styp = 'new ${g.js_name(sym.name)}(${g.to_js_typ_def_val(sym.name)})'
|
||||
|
|
|
@ -459,6 +459,7 @@ fn (mut g JsGen) generic_fn_name(types []ast.Type, before string, is_decl bool)
|
|||
}
|
||||
|
||||
fn (mut g JsGen) gen_method_decl(it ast.FnDecl, typ FnGenType) {
|
||||
cur_fn_decl := g.fn_decl
|
||||
unsafe {
|
||||
g.fn_decl = &it
|
||||
}
|
||||
|
@ -528,7 +529,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl, typ FnGenType) {
|
|||
mut args := it.params
|
||||
|
||||
g.fn_args(args, it.is_variadic)
|
||||
g.write(') {')
|
||||
g.writeln(') {')
|
||||
for i, arg in args {
|
||||
is_varg := i == args.len - 1 && it.is_variadic
|
||||
arg_name := g.js_name(arg.name)
|
||||
|
@ -584,7 +585,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl, typ FnGenType) {
|
|||
}
|
||||
}
|
||||
|
||||
g.fn_decl = voidptr(0)
|
||||
g.fn_decl = cur_fn_decl
|
||||
}
|
||||
|
||||
fn (mut g JsGen) fn_args(args []ast.Param, is_variadic bool) {
|
||||
|
@ -609,6 +610,7 @@ fn (mut g JsGen) gen_anon_fn(mut fun ast.AnonFn) {
|
|||
}
|
||||
fun.has_gen = true
|
||||
it := fun.decl
|
||||
cur_fn_decl := g.fn_decl
|
||||
unsafe {
|
||||
g.fn_decl = &it
|
||||
}
|
||||
|
@ -672,5 +674,5 @@ fn (mut g JsGen) gen_anon_fn(mut fun ast.AnonFn) {
|
|||
g.dec_indent()
|
||||
g.writeln('}})()')
|
||||
|
||||
g.fn_decl = voidptr(0)
|
||||
g.fn_decl = cur_fn_decl
|
||||
}
|
||||
|
|
|
@ -173,11 +173,13 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
|||
}
|
||||
g.enter_namespace('main')
|
||||
// generate JS methods for interface methods
|
||||
for _, iface_types in g.table.iface_types {
|
||||
for iface_name, iface_types in g.table.iface_types {
|
||||
iface := g.table.find_type(iface_name) or { panic('unreachable: interface must exist') }
|
||||
for ty in iface_types {
|
||||
sym := g.table.get_type_symbol(ty)
|
||||
for method in sym.methods {
|
||||
p_sym := g.table.get_type_symbol(method.params[0].typ)
|
||||
|
||||
for method in iface.methods {
|
||||
p_sym := g.table.get_type_symbol(ty)
|
||||
mname := g.js_name(p_sym.name) + '_' + method.name
|
||||
g.write('${g.js_name(sym.name)}.prototype.$method.name = function(')
|
||||
for i, param in method.params {
|
||||
|
@ -1702,6 +1704,10 @@ fn (mut g JsGen) gen_import_stmt(it ast.Import) {
|
|||
}
|
||||
|
||||
fn (mut g JsGen) gen_interface_decl(it ast.InterfaceDecl) {
|
||||
if it.language != .v {
|
||||
// JS interfaces do not need codegen
|
||||
return
|
||||
}
|
||||
// JS is dynamically typed, so we don't need any codegen at all
|
||||
// We just need the JSDoc so TypeScript type checking works
|
||||
g.doc.gen_interface(it)
|
||||
|
@ -1829,6 +1835,17 @@ fn (mut g JsGen) gen_struct_decl(node ast.StructDecl) {
|
|||
etyp := g.typ(embed.typ)
|
||||
g.writeln('...${g.js_name(etyp)}.prototype,')
|
||||
}
|
||||
for iface, iface_types in g.table.iface_types {
|
||||
if iface.starts_with('JS.') {
|
||||
for ty in iface_types {
|
||||
sym := g.table.get_type_symbol(ty)
|
||||
|
||||
if sym.name == node.name {
|
||||
g.writeln('...${g.js_name(iface)}.prototype,')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fns := g.method_fn_decls[name]
|
||||
// gen toString method
|
||||
fn_names := fns.map(it.name)
|
||||
|
@ -2335,7 +2352,9 @@ 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_ {
|
||||
if !sym.name.starts_with('JS.') {
|
||||
g.write('.val')
|
||||
}
|
||||
if branch.exprs[sumtype_index] is ast.TypeNode {
|
||||
g.write(' instanceof ')
|
||||
g.expr(branch.exprs[sumtype_index])
|
||||
|
|
|
@ -450,7 +450,12 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
|||
name_pos := p.tok.position()
|
||||
p.check_for_impure_v(language, name_pos)
|
||||
modless_name := p.check_name()
|
||||
interface_name := p.prepend_mod(modless_name).clone()
|
||||
mut interface_name := ''
|
||||
if language == .js {
|
||||
interface_name = 'JS.' + modless_name
|
||||
} else {
|
||||
interface_name = p.prepend_mod(modless_name)
|
||||
}
|
||||
generic_types, _ := p.parse_generic_types()
|
||||
// println('interface decl $interface_name')
|
||||
p.check(.lcbr)
|
||||
|
@ -472,6 +477,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
|||
is_generic: generic_types.len > 0
|
||||
generic_types: generic_types
|
||||
}
|
||||
language: language
|
||||
)
|
||||
if reg_idx == -1 {
|
||||
p.error_with_pos('cannot register interface `$interface_name`, another type with this name exists',
|
||||
|
@ -492,8 +498,11 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
|||
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
||||
if p.tok.kind == .name && p.tok.lit.len > 0 && p.tok.lit[0].is_capital() {
|
||||
iface_pos := p.tok.position()
|
||||
iface_name := p.tok.lit
|
||||
mut iface_name := p.tok.lit
|
||||
iface_type := p.parse_type()
|
||||
if iface_name == 'JS' {
|
||||
iface_name = p.table.get_type_symbol(iface_type).name
|
||||
}
|
||||
comments := p.eat_comments()
|
||||
ifaces << ast.InterfaceEmbedding{
|
||||
name: iface_name
|
||||
|
|
Loading…
Reference in New Issue