forked from mirrors/gecko-dev
Bug 1872918 - Collect .d.json typescript info from xpidl r=mossop,nika
Differential Revision: https://phabricator.services.mozilla.com/D197618
This commit is contained in:
parent
a267fa11a7
commit
3d22ee1fa3
10 changed files with 1654 additions and 38 deletions
|
|
@ -1490,3 +1490,4 @@ toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated
|
||||||
tools/browsertime/package.json
|
tools/browsertime/package.json
|
||||||
tools/browsertime/package-lock.json
|
tools/browsertime/package-lock.json
|
||||||
try_task_config.json
|
try_task_config.json
|
||||||
|
xpcom/idl-parser/xpidl/fixtures/xpctest.d.json
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import sys
|
||||||
import six
|
import six
|
||||||
from buildconfig import topsrcdir
|
from buildconfig import topsrcdir
|
||||||
from mozpack import path as mozpath
|
from mozpack import path as mozpath
|
||||||
from xpidl import jsonxpt
|
from xpidl import jsonxpt, typescript
|
||||||
from xpidl.header import print_header
|
from xpidl.header import print_header
|
||||||
from xpidl.rust import print_rust_bindings
|
from xpidl.rust import print_rust_bindings
|
||||||
from xpidl.rust_macros import print_rust_macros_bindings
|
from xpidl.rust_macros import print_rust_macros_bindings
|
||||||
|
|
@ -39,6 +39,8 @@ def process(
|
||||||
p = IDLParser()
|
p = IDLParser()
|
||||||
|
|
||||||
xpts = []
|
xpts = []
|
||||||
|
ts_data = []
|
||||||
|
|
||||||
mk = Makefile()
|
mk = Makefile()
|
||||||
rule = mk.create_rule()
|
rule = mk.create_rule()
|
||||||
|
|
||||||
|
|
@ -63,6 +65,7 @@ def process(
|
||||||
rs_bt_path = os.path.join(xpcrs_dir, "bt", "%s.rs" % stem)
|
rs_bt_path = os.path.join(xpcrs_dir, "bt", "%s.rs" % stem)
|
||||||
|
|
||||||
xpts.append(jsonxpt.build_typelib(idl))
|
xpts.append(jsonxpt.build_typelib(idl))
|
||||||
|
ts_data.append(typescript.ts_source(idl))
|
||||||
|
|
||||||
rule.add_dependencies(six.ensure_text(s) for s in idl.deps)
|
rule.add_dependencies(six.ensure_text(s) for s in idl.deps)
|
||||||
|
|
||||||
|
|
@ -94,6 +97,13 @@ def process(
|
||||||
with open(xpt_path, "w", encoding="utf-8", newline="\n") as fh:
|
with open(xpt_path, "w", encoding="utf-8", newline="\n") as fh:
|
||||||
jsonxpt.write(jsonxpt.link(xpts), fh)
|
jsonxpt.write(jsonxpt.link(xpts), fh)
|
||||||
|
|
||||||
|
# NOTE: Make doesn't know about .d.json files, but we can piggy-back
|
||||||
|
# on XPT generation for now, as conceptually they contain the same
|
||||||
|
# information, and should be built together in all cases.
|
||||||
|
ts_path = os.path.join(xpt_dir, f"{module}.d.json")
|
||||||
|
with open(ts_path, "w", encoding="utf-8", newline="\n") as fh:
|
||||||
|
typescript.write(ts_data, fh)
|
||||||
|
|
||||||
rule.add_targets([six.ensure_text(xpt_path)])
|
rule.add_targets([six.ensure_text(xpt_path)])
|
||||||
if deps_dir:
|
if deps_dir:
|
||||||
deps_path = os.path.join(deps_dir, "%s.pp" % module)
|
deps_path = os.path.join(deps_dir, "%s.pp" % module)
|
||||||
|
|
|
||||||
|
|
@ -37,3 +37,4 @@ toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated
|
||||||
tools/browsertime/package.json
|
tools/browsertime/package.json
|
||||||
tools/browsertime/package-lock.json
|
tools/browsertime/package-lock.json
|
||||||
try_task_config.json
|
try_task_config.json
|
||||||
|
xpcom/idl-parser/xpidl/fixtures/xpctest.d.json
|
||||||
|
|
|
||||||
|
|
@ -35,18 +35,21 @@ class Promise;
|
||||||
#if 0
|
#if 0
|
||||||
%}
|
%}
|
||||||
|
|
||||||
typedef boolean bool ;
|
// [substitute] typedefs emit the underlying builtin type directly, and
|
||||||
typedef octet uint8_t ;
|
// avoid polluting bindings for other languages with C++ stdint types.
|
||||||
typedef unsigned short uint16_t ;
|
|
||||||
typedef unsigned short char16_t;
|
|
||||||
typedef unsigned long uint32_t ;
|
|
||||||
typedef unsigned long long uint64_t ;
|
|
||||||
typedef long long PRTime ;
|
|
||||||
typedef short int16_t ;
|
|
||||||
typedef long int32_t ;
|
|
||||||
typedef long long int64_t ;
|
|
||||||
|
|
||||||
typedef unsigned long nsresult ;
|
[substitute] typedef boolean bool ;
|
||||||
|
[substitute] typedef octet uint8_t ;
|
||||||
|
[substitute] typedef unsigned short uint16_t ;
|
||||||
|
[substitute] typedef unsigned long uint32_t ;
|
||||||
|
[substitute] typedef unsigned long long uint64_t ;
|
||||||
|
[substitute] typedef short int16_t ;
|
||||||
|
[substitute] typedef long int32_t ;
|
||||||
|
[substitute] typedef long long int64_t ;
|
||||||
|
|
||||||
|
typedef unsigned short char16_t ;
|
||||||
|
typedef unsigned long nsresult ;
|
||||||
|
typedef long long PRTime ;
|
||||||
|
|
||||||
// If we ever want to use `size_t` in scriptable interfaces, this will need to
|
// If we ever want to use `size_t` in scriptable interfaces, this will need to
|
||||||
// be built into the xpidl compiler, as the size varies based on platform.
|
// be built into the xpidl compiler, as the size varies based on platform.
|
||||||
|
|
|
||||||
1376
xpcom/idl-parser/xpidl/fixtures/xpctest.d.json
Normal file
1376
xpcom/idl-parser/xpidl/fixtures/xpctest.d.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -339,6 +339,8 @@ def print_header(idl, fd, filename, relpath):
|
||||||
write_interface(p, fd)
|
write_interface(p, fd)
|
||||||
continue
|
continue
|
||||||
if p.kind == "typedef":
|
if p.kind == "typedef":
|
||||||
|
if p.substitute:
|
||||||
|
continue
|
||||||
printComments(fd, p.doccomments, "")
|
printComments(fd, p.doccomments, "")
|
||||||
fd.write("typedef %s %s;\n\n" % (p.realtype.nativeType("in"), p.name))
|
fd.write("typedef %s %s;\n\n" % (p.realtype.nativeType("in"), p.name))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
#
|
#
|
||||||
# Unit tests for xpidl.py
|
# Unit tests for xpidl.py
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Hack: the first entry in sys.path is the directory containing the script.
|
# Hack: the first entry in sys.path is the directory containing the script.
|
||||||
|
|
@ -16,7 +18,7 @@ import unittest
|
||||||
|
|
||||||
import mozunit
|
import mozunit
|
||||||
|
|
||||||
from xpidl import header, xpidl
|
from xpidl import header, typescript, xpidl
|
||||||
|
|
||||||
|
|
||||||
class TestParser(unittest.TestCase):
|
class TestParser(unittest.TestCase):
|
||||||
|
|
@ -253,5 +255,42 @@ attribute long bar;
|
||||||
self.assertEqual(e.args[0], ("cannot find symbol 'Y'"))
|
self.assertEqual(e.args[0], ("cannot find symbol 'Y'"))
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypescript(unittest.TestCase):
|
||||||
|
"""A few basic smoke tests for typescript generation."""
|
||||||
|
|
||||||
|
dir = os.path.dirname(__file__)
|
||||||
|
src = os.path.join(dir, "..", "..", "..")
|
||||||
|
|
||||||
|
# We use the xpctest.xpt *.idl files from:
|
||||||
|
tests_dir = os.path.join(src, "js/xpconnect/tests/idl")
|
||||||
|
files = [
|
||||||
|
"xpctest_attributes.idl",
|
||||||
|
"xpctest_bug809674.idl",
|
||||||
|
"xpctest_cenums.idl",
|
||||||
|
"xpctest_interfaces.idl",
|
||||||
|
"xpctest_params.idl",
|
||||||
|
"xpctest_returncode.idl",
|
||||||
|
"xpctest_utils.idl",
|
||||||
|
]
|
||||||
|
|
||||||
|
fixtures = os.path.join(dir, "fixtures")
|
||||||
|
inc_dirs = [os.path.join(src, "xpcom/base")]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.parser = xpidl.IDLParser()
|
||||||
|
|
||||||
|
def test_d_json(self):
|
||||||
|
mods = []
|
||||||
|
for file in self.files:
|
||||||
|
path = os.path.join(self.tests_dir, file)
|
||||||
|
idl = self.parser.parse(open(path).read(), path)
|
||||||
|
idl.resolve(self.inc_dirs, self.parser, {})
|
||||||
|
mods.append(typescript.ts_source(idl))
|
||||||
|
|
||||||
|
result = json.dumps(mods, indent=2, sort_keys=True)
|
||||||
|
expected = open(os.path.join(self.fixtures, "xpctest.d.json")).read()
|
||||||
|
self.assertEqual(result, expected, "types data json does not match")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
mozunit.main(runwith="unittest")
|
mozunit.main(runwith="unittest")
|
||||||
|
|
|
||||||
|
|
@ -363,8 +363,8 @@ def print_rust_bindings(idl, fd, relpath):
|
||||||
|
|
||||||
if p.kind == "typedef":
|
if p.kind == "typedef":
|
||||||
try:
|
try:
|
||||||
# We have to skip the typedef of bool to bool (it doesn't make any sense anyways)
|
# Skip bool and C++ stdint typedefs marked with [substitute].
|
||||||
if p.name == "bool":
|
if p.substitute:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if printdoccomments:
|
if printdoccomments:
|
||||||
|
|
|
||||||
94
xpcom/idl-parser/xpidl/typescript.py
Normal file
94
xpcom/idl-parser/xpidl/typescript.py
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# typescript.py - Collect .d.json TypeScript info from xpidl.
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
import mozpack.path as mozpath
|
||||||
|
|
||||||
|
from xpidl import xpidl
|
||||||
|
|
||||||
|
|
||||||
|
def ts_enum(e):
|
||||||
|
variants = [{"name": v.name, "value": v.getValue()} for v in e.variants]
|
||||||
|
return {"id": e.basename, "variants": variants}
|
||||||
|
|
||||||
|
|
||||||
|
def ts_attribute(a):
|
||||||
|
return {"name": a.name, "type": a.realtype.tsType(), "readonly": a.readonly}
|
||||||
|
|
||||||
|
|
||||||
|
def ts_method(m):
|
||||||
|
args = []
|
||||||
|
for p in m.params:
|
||||||
|
if p.iid_is and not p.retval:
|
||||||
|
raise xpidl.TSNoncompat(f"{m.name} has unsupported iid_is argument")
|
||||||
|
args.append({"name": p.name, "optional": p.optional, "type": p.tsType()})
|
||||||
|
|
||||||
|
iid_is = None
|
||||||
|
type = m.realtype.tsType()
|
||||||
|
if args and m.params[-1].retval:
|
||||||
|
type = args.pop()["type"]
|
||||||
|
iid_is = m.params[-1].iid_is
|
||||||
|
|
||||||
|
return {"name": m.name, "type": type, "iid_is": iid_is, "args": args}
|
||||||
|
|
||||||
|
|
||||||
|
def ts_interface(iface):
|
||||||
|
enums = []
|
||||||
|
consts = []
|
||||||
|
members = []
|
||||||
|
|
||||||
|
for m in iface.members:
|
||||||
|
try:
|
||||||
|
if isinstance(m, xpidl.CEnum):
|
||||||
|
enums.append(ts_enum(m))
|
||||||
|
elif isinstance(m, xpidl.ConstMember):
|
||||||
|
consts.append({"name": m.name, "value": m.getValue()})
|
||||||
|
elif isinstance(m, xpidl.Attribute):
|
||||||
|
members.append(ts_attribute(m))
|
||||||
|
elif isinstance(m, xpidl.Method):
|
||||||
|
members.append(ts_method(m))
|
||||||
|
except xpidl.TSNoncompat:
|
||||||
|
# Omit member if any type is unsupported.
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {
|
||||||
|
"id": iface.name,
|
||||||
|
"base": iface.base,
|
||||||
|
"callable": iface.attributes.function,
|
||||||
|
"enums": enums,
|
||||||
|
"consts": consts,
|
||||||
|
"members": members,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def ts_typedefs(idl):
|
||||||
|
for p in idl.getNames():
|
||||||
|
if isinstance(p, xpidl.Typedef) and not p.substitute:
|
||||||
|
try:
|
||||||
|
yield (p.name, p.realtype.tsType())
|
||||||
|
except xpidl.TSNoncompat:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def ts_source(idl):
|
||||||
|
"""Collect typescript interface .d.json from a source idl file."""
|
||||||
|
root = mozpath.join(mozpath.dirname(__file__), "../../..")
|
||||||
|
return {
|
||||||
|
"path": mozpath.relpath(idl.productions[0].location._file, root),
|
||||||
|
"interfaces": [
|
||||||
|
ts_interface(p)
|
||||||
|
for p in idl.productions
|
||||||
|
if isinstance(p, xpidl.Interface) and p.attributes.scriptable
|
||||||
|
],
|
||||||
|
"typedefs": sorted(ts_typedefs(idl)),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def write(d_json, fd):
|
||||||
|
"""Write json type info into fd"""
|
||||||
|
json.dump(d_json, fd, indent=2, sort_keys=True)
|
||||||
|
|
@ -122,10 +122,13 @@ class Builtin(object):
|
||||||
kind = "builtin"
|
kind = "builtin"
|
||||||
location = BuiltinLocation
|
location = BuiltinLocation
|
||||||
|
|
||||||
def __init__(self, name, nativename, rustname, signed=False, maybeConst=False):
|
def __init__(
|
||||||
|
self, name, nativename, rustname, tsname, signed=False, maybeConst=False
|
||||||
|
):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.nativename = nativename
|
self.nativename = nativename
|
||||||
self.rustname = rustname
|
self.rustname = rustname
|
||||||
|
self.tsname = tsname
|
||||||
self.signed = signed
|
self.signed = signed
|
||||||
self.maybeConst = maybeConst
|
self.maybeConst = maybeConst
|
||||||
|
|
||||||
|
|
@ -171,28 +174,37 @@ class Builtin(object):
|
||||||
|
|
||||||
return "%s%s" % ("*mut " if "out" in calltype else "", rustname)
|
return "%s%s" % ("*mut " if "out" in calltype else "", rustname)
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
if self.tsname:
|
||||||
|
return self.tsname
|
||||||
|
|
||||||
|
raise TSNoncompat(f"Builtin type {self.name} unsupported in TypeScript")
|
||||||
|
|
||||||
|
|
||||||
builtinNames = [
|
builtinNames = [
|
||||||
Builtin("boolean", "bool", "bool"),
|
Builtin("boolean", "bool", "bool", "boolean"),
|
||||||
Builtin("void", "void", "libc::c_void"),
|
Builtin("void", "void", "libc::c_void", "void"),
|
||||||
Builtin("octet", "uint8_t", "u8", False, True),
|
Builtin("octet", "uint8_t", "u8", "u8", False, True),
|
||||||
Builtin("short", "int16_t", "i16", True, True),
|
Builtin("short", "int16_t", "i16", "i16", True, True),
|
||||||
Builtin("long", "int32_t", "i32", True, True),
|
Builtin("long", "int32_t", "i32", "i32", True, True),
|
||||||
Builtin("long long", "int64_t", "i64", True, True),
|
Builtin("long long", "int64_t", "i64", "i64", True, True),
|
||||||
Builtin("unsigned short", "uint16_t", "u16", False, True),
|
Builtin("unsigned short", "uint16_t", "u16", "u16", False, True),
|
||||||
Builtin("unsigned long", "uint32_t", "u32", False, True),
|
Builtin("unsigned long", "uint32_t", "u32", "u32", False, True),
|
||||||
Builtin("unsigned long long", "uint64_t", "u64", False, True),
|
Builtin("unsigned long long", "uint64_t", "u64", "u64", False, True),
|
||||||
Builtin("float", "float", "libc::c_float", True, False),
|
Builtin("float", "float", "libc::c_float", "float"),
|
||||||
Builtin("double", "double", "libc::c_double", True, False),
|
Builtin("double", "double", "libc::c_double", "double"),
|
||||||
Builtin("char", "char", "libc::c_char", True, False),
|
Builtin("char", "char", "libc::c_char", "string"),
|
||||||
Builtin("string", "char *", "*const libc::c_char", False, False),
|
Builtin("string", "char *", "*const libc::c_char", "string"),
|
||||||
Builtin("wchar", "char16_t", "u16", False, False),
|
Builtin("wchar", "char16_t", "u16", "string"),
|
||||||
Builtin("wstring", "char16_t *", "*const u16", False, False),
|
Builtin("wstring", "char16_t *", "*const u16", "string"),
|
||||||
# As seen in mfbt/RefCountType.h, this type has special handling to
|
# As seen in mfbt/RefCountType.h, this type has special handling to
|
||||||
# maintain binary compatibility with MSCOM's IUnknown that cannot be
|
# maintain binary compatibility with MSCOM's IUnknown that cannot be
|
||||||
# expressed in XPIDL.
|
# expressed in XPIDL.
|
||||||
Builtin(
|
Builtin(
|
||||||
"MozExternalRefCountType", "MozExternalRefCountType", "MozExternalRefCountType"
|
"MozExternalRefCountType",
|
||||||
|
"MozExternalRefCountType",
|
||||||
|
"MozExternalRefCountType",
|
||||||
|
None,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -308,6 +320,16 @@ class RustNoncompat(Exception):
|
||||||
return self.reason
|
return self.reason
|
||||||
|
|
||||||
|
|
||||||
|
class TSNoncompat(Exception):
|
||||||
|
"""Raised when a type cannot be exposed to TypeScript."""
|
||||||
|
|
||||||
|
def __init__(self, reason):
|
||||||
|
self.reason = reason
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.reason
|
||||||
|
|
||||||
|
|
||||||
class IDLError(Exception):
|
class IDLError(Exception):
|
||||||
def __init__(self, message, location, warning=False, notes=None):
|
def __init__(self, message, location, warning=False, notes=None):
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
@ -458,12 +480,20 @@ class CDATA(object):
|
||||||
class Typedef(object):
|
class Typedef(object):
|
||||||
kind = "typedef"
|
kind = "typedef"
|
||||||
|
|
||||||
def __init__(self, type, name, location, doccomments):
|
def __init__(self, type, name, attlist, location, doccomments):
|
||||||
self.type = type
|
self.type = type
|
||||||
self.name = name
|
self.name = name
|
||||||
self.location = location
|
self.location = location
|
||||||
self.doccomments = doccomments
|
self.doccomments = doccomments
|
||||||
|
|
||||||
|
# C++ stdint types and the bool typedef from nsrootidl.idl are marked
|
||||||
|
# with [substitute], and emit as the underlying builtin type directly.
|
||||||
|
self.substitute = False
|
||||||
|
for name, value, aloc in attlist:
|
||||||
|
if name != "substitute" or value is not None:
|
||||||
|
raise IDLError(f"Unexpected attribute {name}({value})", aloc)
|
||||||
|
self.substitute = True
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.name == other.name and self.type == other.type
|
return self.name == other.name and self.type == other.type
|
||||||
|
|
||||||
|
|
@ -475,14 +505,26 @@ class Typedef(object):
|
||||||
raise IDLError("Unsupported typedef target type", self.location)
|
raise IDLError("Unsupported typedef target type", self.location)
|
||||||
|
|
||||||
def nativeType(self, calltype):
|
def nativeType(self, calltype):
|
||||||
|
if self.substitute:
|
||||||
|
return self.realtype.nativeType(calltype)
|
||||||
|
|
||||||
return "%s %s" % (self.name, "*" if "out" in calltype else "")
|
return "%s %s" % (self.name, "*" if "out" in calltype else "")
|
||||||
|
|
||||||
def rustType(self, calltype):
|
def rustType(self, calltype):
|
||||||
|
if self.substitute:
|
||||||
|
return self.realtype.rustType(calltype)
|
||||||
|
|
||||||
if self.name == "nsresult":
|
if self.name == "nsresult":
|
||||||
return "%s::nserror::nsresult" % ("*mut " if "out" in calltype else "")
|
return "%s::nserror::nsresult" % ("*mut " if "out" in calltype else "")
|
||||||
|
|
||||||
return "%s%s" % ("*mut " if "out" in calltype else "", self.name)
|
return "%s%s" % ("*mut " if "out" in calltype else "", self.name)
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
if self.substitute:
|
||||||
|
return self.realtype.tsType()
|
||||||
|
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "typedef %s %s\n" % (self.type, self.name)
|
return "typedef %s %s\n" % (self.type, self.name)
|
||||||
|
|
||||||
|
|
@ -524,6 +566,9 @@ class Forward(object):
|
||||||
return "Option<RefPtr<%s>>" % self.name
|
return "Option<RefPtr<%s>>" % self.name
|
||||||
return "%s*const %s" % ("*mut" if "out" in calltype else "", self.name)
|
return "%s*const %s" % ("*mut" if "out" in calltype else "", self.name)
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "forward-declared %s\n" % self.name
|
return "forward-declared %s\n" % self.name
|
||||||
|
|
||||||
|
|
@ -701,6 +746,21 @@ class Native(object):
|
||||||
|
|
||||||
raise RustNoncompat("native type %s unsupported" % self.nativename)
|
raise RustNoncompat("native type %s unsupported" % self.nativename)
|
||||||
|
|
||||||
|
ts_special = {
|
||||||
|
"astring": "string",
|
||||||
|
"cstring": "string",
|
||||||
|
"jsval": "any",
|
||||||
|
"nsid": "nsID",
|
||||||
|
"promise": "Promise<any>",
|
||||||
|
"utf8string": "string",
|
||||||
|
}
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
if type := self.ts_special.get(self.specialtype, None):
|
||||||
|
return type
|
||||||
|
|
||||||
|
raise TSNoncompat(f"Native type {self.name} unsupported in TypeScript")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "native %s(%s)\n" % (self.name, self.nativename)
|
return "native %s(%s)\n" % (self.name, self.nativename)
|
||||||
|
|
||||||
|
|
@ -749,6 +809,9 @@ class WebIDL(object):
|
||||||
# Just expose the type as a void* - we can't do any better.
|
# Just expose the type as a void* - we can't do any better.
|
||||||
return "%s*const libc::c_void" % ("*mut " if "out" in calltype else "")
|
return "%s*const libc::c_void" % ("*mut " if "out" in calltype else "")
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "webidl %s\n" % self.name
|
return "webidl %s\n" % self.name
|
||||||
|
|
||||||
|
|
@ -923,6 +986,9 @@ class Interface(object):
|
||||||
total += realbase.countEntries()
|
total += realbase.countEntries()
|
||||||
return total
|
return total
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class InterfaceAttributes(object):
|
class InterfaceAttributes(object):
|
||||||
uuid = None
|
uuid = None
|
||||||
|
|
@ -1110,6 +1176,9 @@ class CEnum(object):
|
||||||
def rustType(self, calltype):
|
def rustType(self, calltype):
|
||||||
return "%s u%d" % ("*mut" if "out" in calltype else "", self.width)
|
return "%s u%d" % ("*mut" if "out" in calltype else "", self.width)
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
return f"{self.iface.name}.{self.basename}"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
body = ", ".join("%s = %s" % v for v in self.variants)
|
body = ", ".join("%s = %s" % v for v in self.variants)
|
||||||
return "\tcenum %s : %d { %s };\n" % (self.name, self.width, body)
|
return "\tcenum %s : %d { %s };\n" % (self.name, self.width, body)
|
||||||
|
|
@ -1523,8 +1592,22 @@ class Param(object):
|
||||||
self.name,
|
self.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
# A generic retval param type needs special handling.
|
||||||
|
if self.retval and self.iid_is:
|
||||||
|
return "nsQIResult"
|
||||||
|
|
||||||
|
type = self.realtype.tsType()
|
||||||
|
if self.paramtype == "inout":
|
||||||
|
return f"InOutParam<{type}>"
|
||||||
|
if self.paramtype == "out":
|
||||||
|
return f"OutParam<{type}>"
|
||||||
|
return type
|
||||||
|
|
||||||
|
|
||||||
class LegacyArray(object):
|
class LegacyArray(object):
|
||||||
|
kind = "legacyarray"
|
||||||
|
|
||||||
def __init__(self, basetype):
|
def __init__(self, basetype):
|
||||||
self.type = basetype
|
self.type = basetype
|
||||||
self.location = self.type.location
|
self.location = self.type.location
|
||||||
|
|
@ -1555,6 +1638,9 @@ class LegacyArray(object):
|
||||||
self.type.rustType("legacyelement"),
|
self.type.rustType("legacyelement"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
return self.type.tsType() + "[]"
|
||||||
|
|
||||||
|
|
||||||
class Array(object):
|
class Array(object):
|
||||||
kind = "array"
|
kind = "array"
|
||||||
|
|
@ -1594,6 +1680,9 @@ class Array(object):
|
||||||
else:
|
else:
|
||||||
return base
|
return base
|
||||||
|
|
||||||
|
def tsType(self):
|
||||||
|
return self.type.tsType() + "[]"
|
||||||
|
|
||||||
|
|
||||||
TypeId = namedtuple("TypeId", "name params")
|
TypeId = namedtuple("TypeId", "name params")
|
||||||
|
|
||||||
|
|
@ -1751,12 +1840,13 @@ class IDLParser(object):
|
||||||
p[0].insert(0, p[1])
|
p[0].insert(0, p[1])
|
||||||
|
|
||||||
def p_typedef(self, p):
|
def p_typedef(self, p):
|
||||||
"""typedef : TYPEDEF type IDENTIFIER ';'"""
|
"""typedef : attributes TYPEDEF type IDENTIFIER ';'"""
|
||||||
p[0] = Typedef(
|
p[0] = Typedef(
|
||||||
type=p[2],
|
type=p[3],
|
||||||
name=p[3],
|
name=p[4],
|
||||||
location=self.getLocation(p, 1),
|
attlist=p[1]["attlist"],
|
||||||
doccomments=p.slice[1].doccomments,
|
location=self.getLocation(p, 2),
|
||||||
|
doccomments=getattr(p[1], "doccomments", []) + p.slice[2].doccomments,
|
||||||
)
|
)
|
||||||
|
|
||||||
def p_native(self, p):
|
def p_native(self, p):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue