Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/xpcom/idl-parser/xpidl/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  jsonxpt.py   Sprache: Python

 
#!/usr/bin/env python
# jsonxpt.py - Generate json XPT typelib files from IDL.
#
# 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/.

"""Generate a json XPT typelib for an IDL file"""

import itertools
import json

from xpidl import xpidl

# A map of xpidl.py types to xpt enum variants
TypeMap = {
    # builtins
    "boolean""TD_BOOL",
    "void""TD_VOID",
    "int8_t""TD_INT8",
    "int16_t""TD_INT16",
    "int32_t""TD_INT32",
    "int64_t""TD_INT64",
    "uint8_t""TD_UINT8",
    "uint16_t""TD_UINT16",
    "uint32_t""TD_UINT32",
    "uint64_t""TD_UINT64",
    "nsresult""TD_UINT32",
    "float""TD_FLOAT",
    "double""TD_DOUBLE",
    "char""TD_CHAR",
    "string""TD_PSTRING",
    "wchar""TD_WCHAR",
    "wstring""TD_PWSTRING",
    "char16_t""TD_UINT16",
    # special types
    "nsid""TD_NSID",
    "astring""TD_ASTRING",
    "utf8string""TD_UTF8STRING",
    "cstring""TD_CSTRING",
    "jsval""TD_JSVAL",
    "promise""TD_PROMISE",
}


def flags(*flags):
    return [flag for flag, cond in flags if cond]


def get_type(type, calltype, iid_is=None, size_is=None, needs_scriptable=None):
    while isinstance(type, xpidl.Typedef):
        type = type.realtype

    if isinstance(type, xpidl.Builtin):
        ret = {"tag": TypeMap[type.name]}
        if type.name in ["string""wstring"and size_is is not None:
            ret["tag"] += "_SIZE_IS"
            ret["size_is"] = size_is
        return ret

    if isinstance(type, xpidl.Array):
        # NB: For a Array<T> we pass down the iid_is to get the type of T.
        #     This allows Arrays of InterfaceIs types to work.
        return {
            "tag""TD_ARRAY",
            "element": get_type(type.type, calltype, iid_is, None, needs_scriptable),
        }

    if isinstance(type, xpidl.LegacyArray):
        # NB: For a Legacy [array] T we pass down iid_is to get the type of T.
        #     This allows [array] of InterfaceIs types to work.
        return {
            "tag""TD_LEGACY_ARRAY",
            "size_is": size_is,
            "element": get_type(type.type, calltype, iid_is, None, needs_scriptable),
        }

    if isinstance(type, xpidl.Interface) or isinstance(type, xpidl.Forward):
        if isinstance(needs_scriptable, set):
            needs_scriptable.add(type.name)
        return {
            "tag""TD_INTERFACE_TYPE",
            "name": type.name,
        }

    if isinstance(type, xpidl.WebIDL):
        return {
            "tag""TD_DOMOBJECT",
            "name": type.name,
            "native": type.native,
            "headerFile": type.headerFile,
        }

    if isinstance(type, xpidl.Native):
        if type.specialtype == "nsid" and type.isPtr(calltype):
            return {"tag""TD_NSIDPTR"}
        elif type.specialtype:
            return {"tag": TypeMap[type.specialtype]}
        elif iid_is is not None:
            return {
                "tag""TD_INTERFACE_IS_TYPE",
                "iid_is": iid_is,
            }
        else:
            return {"tag""TD_VOID"}

    if isinstance(type, xpidl.CEnum):
        # As far as XPConnect is concerned, cenums are just unsigned integers.
        return {"tag""TD_UINT%d" % type.width}

    raise Exception("Unknown type!")


def mk_param(type, in_=0, out=0, optional=0):
    return {
        "type": type,
        "flags": flags(
            ("in", in_),
            ("out", out),
            ("optional", optional),
        ),
    }


def mk_method(method, params, getter=0, setter=0, optargc=0, hasretval=0, symbol=0):
    return {
        "name": method.name,
        # NOTE: We don't include any return value information here, as we'll
        # never call the methods if they're marked notxpcom, and all xpcom
        # methods return the same type (nsresult).
        # XXX: If we ever use these files for other purposes than xptcodegen we
        # may want to write that info.
        "params": params,
        "flags": flags(
            ("getter", getter),
            ("setter", setter),
            ("hidden"not method.isScriptable()),
            ("optargc", optargc),
            ("jscontext", method.implicit_jscontext),
            ("hasretval", hasretval),
            ("symbol", method.symbol),
        ),
    }


def attr_param_idx(p, m, attr):
    attr_val = getattr(p, attr, None)
    if not attr_val:
        return None
    for i, param in enumerate(m.params):
        if param.name == attr_val:
            return i
    raise Exception(f"Need parameter named '{attr_val}' for attribute '{attr}'")


def build_interface(iface):
    if iface.namemap is None:
        raise Exception("Interface was not resolved.")

    assert (
        iface.attributes.scriptable
    ), "Don't generate XPT info for non-scriptable interfaces"

    # State used while building an interface
    consts = []
    methods = []

    # Interfaces referenced from scriptable members need to be [scriptable].
    needs_scriptable = set()

    def build_const(c):
        consts.append(
            {
                "name": c.name,
                "type": get_type(c.basetype, ""),
                "value": c.getValue(),  # All of our consts are numbers
            }
        )

    def build_cenum(b):
        for var in b.variants:
            consts.append(
                {
                    "name": var.name,
                    "type": get_type(b, "in"),
                    "value": var.value,
                }
            )

    def build_method(m, needs_scriptable=None):
        params = []
        for p in m.params:
            params.append(
                mk_param(
                    get_type(
                        p.realtype,
                        p.paramtype,
                        iid_is=attr_param_idx(p, m, "iid_is"),
                        size_is=attr_param_idx(p, m, "size_is"),
                        needs_scriptable=needs_scriptable,
                    ),
                    in_=p.paramtype.count("in"),
                    out=p.paramtype.count("out"),
                    optional=p.optional,
                )
            )

        hasretval = len(m.params) > 0 and m.params[-1].retval
        if not m.notxpcom and m.realtype.name != "void":
            hasretval = True
            type = get_type(m.realtype, "out", needs_scriptable=needs_scriptable)
            params.append(mk_param(type, out=1))

        methods.append(
            mk_method(m, params, optargc=m.optional_argc, hasretval=hasretval)
        )

    def build_attr(a, needs_scriptable=None):
        assert a.realtype.name != "void"

        # Write the getter
        getter_params = []
        if not a.notxpcom:
            type = get_type(a.realtype, "out", needs_scriptable=needs_scriptable)
            getter_params.append(mk_param(type, out=1))

        methods.append(mk_method(a, getter_params, getter=1, hasretval=1))

        # And maybe the setter
        if not a.readonly:
            type = get_type(a.realtype, "in", needs_scriptable=needs_scriptable)
            methods.append(mk_method(a, [mk_param(type, in_=1)], setter=1))

    for member in iface.members:
        if isinstance(member, xpidl.ConstMember):
            build_const(member)
        elif isinstance(member, xpidl.Attribute):
            build_attr(member, member.isScriptable() and needs_scriptable)
        elif isinstance(member, xpidl.Method):
            build_method(member, member.isScriptable() and needs_scriptable)
        elif isinstance(member, xpidl.CEnum):
            build_cenum(member)
        elif isinstance(member, xpidl.CDATA):
            pass
        else:
            raise Exception("Unexpected interface member: %s" % member)

    for ref in set(needs_scriptable):
        p = iface.idl.getName(xpidl.TypeId(ref), None)
        if isinstance(p, xpidl.Interface):
            needs_scriptable.remove(ref)
            if not p.attributes.scriptable:
                raise Exception(
                    f"Scriptable member in {iface.name} references non-scriptable {ref}. "
                    "The interface must be marked as [scriptable], "
                    "or the referencing member with [noscript]."
                )

    return {
        "name": iface.name,
        "uuid": iface.attributes.uuid,
        "methods": methods,
        "consts": consts,
        "parent": iface.base,
        "needs_scriptable": sorted(needs_scriptable),
        "flags": flags(
            ("function", iface.attributes.function),
            ("builtinclass", iface.attributes.builtinclass),
            ("main_process_only", iface.attributes.main_process_scriptable_only),
        ),
    }


# These functions are the public interface of this module. They are very simple
# functions, but are exported so that if we need to do something more
# complex in them in the future we can.


def build_typelib(idl):
    """Given a parsed IDL file, generate and return the typelib"""
    return [
        build_interface(p)
        for p in idl.productions
        if p.kind == "interface" and p.attributes.scriptable
    ]


def link(typelibs):
    """Link a list of typelibs together into a single typelib"""
    linked = list(itertools.chain.from_iterable(typelibs))
    assert len(set(iface["name"for iface in linked)) == len(
        linked
    ), "Multiple typelibs containing the same interface were linked together"
    return linked


def write(typelib, fd):
    """Write typelib into fd"""
    json.dump(typelib, fd, indent=2, sort_keys=True)

Messung V0.5
C=91 H=86 G=88

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.