aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/bindings/codegen
diff options
context:
space:
mode:
authorJack Moffitt <jack@metajack.im>2014-08-28 09:34:23 -0600
committerJack Moffitt <jack@metajack.im>2014-09-08 20:21:42 -0600
commitc6ab60dbfc6da7b4f800c9e40893c8b58413960c (patch)
treed1d74076cf7fa20e4f77ec7cb82cae98b67362cb /src/components/script/dom/bindings/codegen
parentdb2f642c32fc5bed445bb6f2e45b0f6f0b4342cf (diff)
downloadservo-c6ab60dbfc6da7b4f800c9e40893c8b58413960c.tar.gz
servo-c6ab60dbfc6da7b4f800c9e40893c8b58413960c.zip
Cargoify servo
Diffstat (limited to 'src/components/script/dom/bindings/codegen')
-rw-r--r--src/components/script/dom/bindings/codegen/BindingGen.py52
-rw-r--r--src/components/script/dom/bindings/codegen/BindingUtils.cpp633
-rw-r--r--src/components/script/dom/bindings/codegen/BindingUtils.h1151
-rw-r--r--src/components/script/dom/bindings/codegen/Bindings.conf28
-rw-r--r--src/components/script/dom/bindings/codegen/Codegen.py5788
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py5534
-rw-r--r--src/components/script/dom/bindings/codegen/Configuration.py341
-rw-r--r--src/components/script/dom/bindings/codegen/DOMJSClass.h114
-rw-r--r--src/components/script/dom/bindings/codegen/DOMJSProxyHandler.cpp247
-rw-r--r--src/components/script/dom/bindings/codegen/DOMJSProxyHandler.h109
-rw-r--r--src/components/script/dom/bindings/codegen/ErrorResult.h59
-rw-r--r--src/components/script/dom/bindings/codegen/Errors.msg30
-rw-r--r--src/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py26
-rw-r--r--src/components/script/dom/bindings/codegen/GlobalGen.py83
-rw-r--r--src/components/script/dom/bindings/codegen/Makefile.in165
-rw-r--r--src/components/script/dom/bindings/codegen/Nullable.h68
-rw-r--r--src/components/script/dom/bindings/codegen/PrimitiveConversions.h350
-rw-r--r--src/components/script/dom/bindings/codegen/RegisterBindings.h14
-rw-r--r--src/components/script/dom/bindings/codegen/TypedArray.h121
-rw-r--r--src/components/script/dom/bindings/codegen/crashtests/769464.html11
-rw-r--r--src/components/script/dom/bindings/codegen/crashtests/crashtests.list1
-rw-r--r--src/components/script/dom/bindings/codegen/parser/README1
-rw-r--r--src/components/script/dom/bindings/codegen/parser/UPSTREAM1
-rw-r--r--src/components/script/dom/bindings/codegen/parser/WebIDL.py5583
-rw-r--r--src/components/script/dom/bindings/codegen/parser/external.patch49
-rw-r--r--src/components/script/dom/bindings/codegen/parser/module.patch12
-rw-r--r--src/components/script/dom/bindings/codegen/parser/runtests.py79
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_any_null.py14
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py14
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py14
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py13
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py84
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_attr.py302
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py67
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py11
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_builtins.py41
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_callback.py34
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py47
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_const.py64
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_constructor.py75
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py28
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py15
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py198
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py150
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_double_null.py14
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py84
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py14
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_enum.py81
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py13
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py20
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py28
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py107
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py15
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_implements.py216
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py18
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py44
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_interface.py188
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py15
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py60
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_method.py145
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py126
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py14
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py14
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_overload.py47
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_sanity.py7
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py294
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py73
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py62
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py56
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_typedef.py76
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_union.py169
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_union_any.py14
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py53
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py10
-rw-r--r--src/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py39
-rwxr-xr-xsrc/components/script/dom/bindings/codegen/parser/update.sh3
-rw-r--r--src/components/script/dom/bindings/codegen/ply/COPYING28
-rw-r--r--src/components/script/dom/bindings/codegen/ply/README9
-rw-r--r--src/components/script/dom/bindings/codegen/ply/ply/__init__.py4
-rw-r--r--src/components/script/dom/bindings/codegen/ply/ply/lex.py1058
-rw-r--r--src/components/script/dom/bindings/codegen/ply/ply/yacc.py3276
-rw-r--r--src/components/script/dom/bindings/codegen/pythonpath.py60
-rw-r--r--src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.cpp40
-rw-r--r--src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.h40
-rw-r--r--src/components/script/dom/bindings/codegen/stubgenerator/generate.sh16
-rw-r--r--src/components/script/dom/bindings/codegen/test/Makefile.in87
-rw-r--r--src/components/script/dom/bindings/codegen/test/TestBindingHeader.h653
-rw-r--r--src/components/script/dom/bindings/codegen/test/TestCodeGen.webidl442
-rw-r--r--src/components/script/dom/bindings/codegen/test/TestDictionary.webidl9
-rw-r--r--src/components/script/dom/bindings/codegen/test/TestTypedef.webidl7
-rw-r--r--src/components/script/dom/bindings/codegen/test/file_bug775543.html5
-rw-r--r--src/components/script/dom/bindings/codegen/test/forOf_iframe.html13
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_InstanceOf.html28
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_bug773326.html11
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_bug775543.html37
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_bug788369.html30
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_enums.html15
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_forOf.html94
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_integers.html45
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_interfaceToString.html38
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_lookupGetter.html49
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_sequence_wrapping.html60
-rw-r--r--src/components/script/dom/bindings/codegen/test/test_traceProtos.html37
103 files changed, 0 insertions, 30131 deletions
diff --git a/src/components/script/dom/bindings/codegen/BindingGen.py b/src/components/script/dom/bindings/codegen/BindingGen.py
deleted file mode 100644
index 408280dacfb..00000000000
--- a/src/components/script/dom/bindings/codegen/BindingGen.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# 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 sys
-sys.path.append("./parser/")
-sys.path.append("./ply/")
-import os
-import cPickle
-import WebIDL
-from Configuration import *
-from CodegenRust import CGBindingRoot, replaceFileIfChanged
-
-def generate_binding_rs(config, outputprefix, webidlfile):
- """
- |config| Is the configuration object.
- |outputprefix| is a prefix to use for the header guards and filename.
- """
-
- filename = outputprefix + ".rs"
- root = CGBindingRoot(config, outputprefix, webidlfile)
- if replaceFileIfChanged(filename, root.define()):
- print "Generating binding implementation: %s" % (filename)
-
-def main():
- # Parse arguments.
- from optparse import OptionParser
- usagestring = "usage: %prog configFile outputPrefix webIDLFile"
- o = OptionParser(usage=usagestring)
- o.add_option("--verbose-errors", action='store_true', default=False,
- help="When an error happens, display the Python traceback.")
- (options, args) = o.parse_args()
-
- if len(args) != 3:
- o.error(usagestring)
- configFile = os.path.normpath(args[0])
- outputPrefix = args[1]
- webIDLFile = os.path.normpath(args[2])
-
- # Load the parsing results
- f = open('ParserResults.pkl', 'rb')
- parserData = cPickle.load(f)
- f.close()
-
- # Create the configuration data.
- config = Configuration(configFile, parserData)
-
- # Generate the prototype classes.
- generate_binding_rs(config, outputPrefix, webIDLFile);
-
-if __name__ == '__main__':
- main()
diff --git a/src/components/script/dom/bindings/codegen/BindingUtils.cpp b/src/components/script/dom/bindings/codegen/BindingUtils.cpp
deleted file mode 100644
index 27ac92e3596..00000000000
--- a/src/components/script/dom/bindings/codegen/BindingUtils.cpp
+++ /dev/null
@@ -1,633 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
-/* 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/. */
-
-#include <stdarg.h>
-
-#include "BindingUtils.h"
-
-#include "WrapperFactory.h"
-#include "xpcprivate.h"
-#include "XPCQuickStubs.h"
-
-namespace mozilla {
-namespace dom {
-
-JSErrorFormatString ErrorFormatString[] = {
-#define MSG_DEF(_name, _argc, _str) \
- { _str, _argc, JSEXN_TYPEERR },
-#include "mozilla/dom/Errors.msg"
-#undef MSG_DEF
-};
-
-const JSErrorFormatString*
-GetErrorMessage(void* aUserRef, const char* aLocale,
- const unsigned aErrorNumber)
-{
- MOZ_ASSERT(aErrorNumber < ArrayLength(ErrorFormatString));
- return &ErrorFormatString[aErrorNumber];
-}
-
-bool
-ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...)
-{
- va_list ap;
- va_start(ap, aErrorNumber);
- JS_ReportErrorNumberVA(aCx, GetErrorMessage, NULL,
- static_cast<const unsigned>(aErrorNumber), ap);
- va_end(ap);
- return false;
-}
-
-bool
-DefineConstants(JSContext* cx, JSObject* obj, ConstantSpec* cs)
-{
- for (; cs->name; ++cs) {
- JSBool ok =
- JS_DefineProperty(cx, obj, cs->name, cs->value, NULL, NULL,
- JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
- if (!ok) {
- return false;
- }
- }
- return true;
-}
-
-static inline bool
-Define(JSContext* cx, JSObject* obj, JSFunctionSpec* spec) {
- return JS_DefineFunctions(cx, obj, spec);
-}
-static inline bool
-Define(JSContext* cx, JSObject* obj, JSPropertySpec* spec) {
- return JS_DefineProperties(cx, obj, spec);
-}
-static inline bool
-Define(JSContext* cx, JSObject* obj, ConstantSpec* spec) {
- return DefineConstants(cx, obj, spec);
-}
-
-template<typename T>
-bool
-DefinePrefable(JSContext* cx, JSObject* obj, Prefable<T>* props)
-{
- MOZ_ASSERT(props);
- MOZ_ASSERT(props->specs);
- do {
- // Define if enabled
- if (props->enabled) {
- if (!Define(cx, obj, props->specs)) {
- return false;
- }
- }
- } while ((++props)->specs);
- return true;
-}
-
-// We should use JSFunction objects for interface objects, but we need a custom
-// hasInstance hook because we have new interface objects on prototype chains of
-// old (XPConnect-based) bindings. Because Function.prototype.toString throws if
-// passed a non-Function object we also need to provide our own toString method
-// for interface objects.
-
-enum {
- TOSTRING_CLASS_RESERVED_SLOT = 0,
- TOSTRING_NAME_RESERVED_SLOT = 1
-};
-
-JSBool
-InterfaceObjectToString(JSContext* cx, unsigned argc, JS::Value *vp)
-{
- JSObject* callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
-
- JSObject* obj = JS_THIS_OBJECT(cx, vp);
- if (!obj) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
- "null", "object");
- return false;
- }
-
- jsval v = js::GetFunctionNativeReserved(callee, TOSTRING_CLASS_RESERVED_SLOT);
- JSClass* clasp = static_cast<JSClass*>(JSVAL_TO_PRIVATE(v));
-
- v = js::GetFunctionNativeReserved(callee, TOSTRING_NAME_RESERVED_SLOT);
- JSString* jsname = static_cast<JSString*>(JSVAL_TO_STRING(v));
- size_t length;
- const jschar* name = JS_GetInternedStringCharsAndLength(jsname, &length);
-
- if (js::GetObjectJSClass(obj) != clasp) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
- NS_ConvertUTF16toUTF8(name).get(), "toString",
- "object");
- return false;
- }
-
- nsString str;
- str.AppendLiteral("function ");
- str.Append(name, length);
- str.AppendLiteral("() {");
- str.Append('\n');
- str.AppendLiteral(" [native code]");
- str.Append('\n');
- str.AppendLiteral("}");
-
- return xpc::NonVoidStringToJsval(cx, str, vp);
-}
-
-static JSObject*
-CreateInterfaceObject(JSContext* cx, JSObject* global, JSObject* receiver,
- JSClass* constructorClass, JSNative constructorNative,
- unsigned ctorNargs, JSObject* proto,
- Prefable<JSFunctionSpec>* staticMethods,
- Prefable<ConstantSpec>* constants,
- const char* name)
-{
- JSObject* constructor;
- if (constructorClass) {
- JSObject* functionProto = JS_GetFunctionPrototype(cx, global);
- if (!functionProto) {
- return NULL;
- }
- constructor = JS_NewObject(cx, constructorClass, functionProto, global);
- } else {
- MOZ_ASSERT(constructorNative);
- JSFunction* fun = JS_NewFunction(cx, constructorNative, ctorNargs,
- JSFUN_CONSTRUCTOR, global, name);
- if (!fun) {
- return NULL;
- }
- constructor = JS_GetFunctionObject(fun);
- }
- if (!constructor) {
- return NULL;
- }
-
- if (staticMethods && !DefinePrefable(cx, constructor, staticMethods)) {
- return NULL;
- }
-
- if (constructorClass) {
- JSFunction* toString = js::DefineFunctionWithReserved(cx, constructor,
- "toString",
- InterfaceObjectToString,
- 0, 0);
- if (!toString) {
- return NULL;
- }
-
- JSObject* toStringObj = JS_GetFunctionObject(toString);
- js::SetFunctionNativeReserved(toStringObj, TOSTRING_CLASS_RESERVED_SLOT,
- PRIVATE_TO_JSVAL(constructorClass));
-
- JSString *str = ::JS_InternString(cx, name);
- if (!str) {
- return NULL;
- }
- js::SetFunctionNativeReserved(toStringObj, TOSTRING_NAME_RESERVED_SLOT,
- STRING_TO_JSVAL(str));
- }
-
- if (constants && !DefinePrefable(cx, constructor, constants)) {
- return NULL;
- }
-
- if (proto && !JS_LinkConstructorAndPrototype(cx, constructor, proto)) {
- return NULL;
- }
-
- JSBool alreadyDefined;
- if (!JS_AlreadyHasOwnProperty(cx, receiver, name, &alreadyDefined)) {
- return NULL;
- }
-
- // This is Enumerable: False per spec.
- if (!alreadyDefined &&
- !JS_DefineProperty(cx, receiver, name, OBJECT_TO_JSVAL(constructor), NULL,
- NULL, 0)) {
- return NULL;
- }
-
- return constructor;
-}
-
-static JSObject*
-CreateInterfacePrototypeObject(JSContext* cx, JSObject* global,
- JSObject* parentProto, JSClass* protoClass,
- Prefable<JSFunctionSpec>* methods,
- Prefable<JSPropertySpec>* properties,
- Prefable<ConstantSpec>* constants)
-{
- JSObject* ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto,
- global);
- if (!ourProto) {
- return NULL;
- }
-
- if (methods && !DefinePrefable(cx, ourProto, methods)) {
- return NULL;
- }
-
- if (properties && !DefinePrefable(cx, ourProto, properties)) {
- return NULL;
- }
-
- if (constants && !DefinePrefable(cx, ourProto, constants)) {
- return NULL;
- }
-
- return ourProto;
-}
-
-JSObject*
-CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject *receiver,
- JSObject* protoProto, JSClass* protoClass,
- JSClass* constructorClass, JSNative constructor,
- unsigned ctorNargs, const DOMClass* domClass,
- Prefable<JSFunctionSpec>* methods,
- Prefable<JSPropertySpec>* properties,
- Prefable<ConstantSpec>* constants,
- Prefable<JSFunctionSpec>* staticMethods, const char* name)
-{
- MOZ_ASSERT(protoClass || constructorClass || constructor,
- "Need at least one class or a constructor!");
- MOZ_ASSERT(!(methods || properties) || protoClass,
- "Methods or properties but no protoClass!");
- MOZ_ASSERT(!staticMethods || constructorClass || constructor,
- "Static methods but no constructorClass or constructor!");
- MOZ_ASSERT(bool(name) == bool(constructorClass || constructor),
- "Must have name precisely when we have an interface object");
- MOZ_ASSERT(!constructorClass || !constructor);
-
- JSObject* proto;
- if (protoClass) {
- proto = CreateInterfacePrototypeObject(cx, global, protoProto, protoClass,
- methods, properties, constants);
- if (!proto) {
- return NULL;
- }
-
- js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
- JS::PrivateValue(const_cast<DOMClass*>(domClass)));
- }
- else {
- proto = NULL;
- }
-
- JSObject* interface;
- if (constructorClass || constructor) {
- interface = CreateInterfaceObject(cx, global, receiver, constructorClass,
- constructor, ctorNargs, proto,
- staticMethods, constants, name);
- if (!interface) {
- return NULL;
- }
- }
-
- return protoClass ? proto : interface;
-}
-
-static bool
-NativeInterface2JSObjectAndThrowIfFailed(XPCLazyCallContext& aLccx,
- JSContext* aCx,
- JS::Value* aRetval,
- xpcObjectHelper& aHelper,
- const nsIID* aIID,
- bool aAllowNativeWrapper)
-{
- nsresult rv;
- if (!XPCConvert::NativeInterface2JSObject(aLccx, aRetval, NULL, aHelper, aIID,
- NULL, aAllowNativeWrapper, &rv)) {
- // I can't tell if NativeInterface2JSObject throws JS exceptions
- // or not. This is a sloppy stab at the right semantics; the
- // method really ought to be fixed to behave consistently.
- if (!JS_IsExceptionPending(aCx)) {
- Throw<true>(aCx, NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED);
- }
- return false;
- }
- return true;
-}
-
-bool
-DoHandleNewBindingWrappingFailure(JSContext* cx, JSObject* scope,
- nsISupports* value, JS::Value* vp)
-{
- if (JS_IsExceptionPending(cx)) {
- return false;
- }
-
- XPCLazyCallContext lccx(JS_CALLER, cx, scope);
-
- if (value) {
- xpcObjectHelper helper(value);
- return NativeInterface2JSObjectAndThrowIfFailed(lccx, cx, vp, helper, NULL,
- true);
- }
-
- return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
-}
-
-// Can only be called with the immediate prototype of the instance object. Can
-// only be called on the prototype of an object known to be a DOM instance.
-JSBool
-InstanceClassHasProtoAtDepth(JSHandleObject protoObject, uint32_t protoID,
- uint32_t depth)
-{
- const DOMClass* domClass = static_cast<DOMClass*>(
- js::GetReservedSlot(protoObject, DOM_PROTO_INSTANCE_CLASS_SLOT).toPrivate());
- return (uint32_t)domClass->mInterfaceChain[depth] == protoID;
-}
-
-// Only set allowNativeWrapper to false if you really know you need it, if in
-// doubt use true. Setting it to false disables security wrappers.
-bool
-XPCOMObjectToJsval(JSContext* cx, JSObject* scope, xpcObjectHelper &helper,
- const nsIID* iid, bool allowNativeWrapper, JS::Value* rval)
-{
- XPCLazyCallContext lccx(JS_CALLER, cx, scope);
-
- if (!NativeInterface2JSObjectAndThrowIfFailed(lccx, cx, rval, helper, iid,
- allowNativeWrapper)) {
- return false;
- }
-
-#ifdef DEBUG
- JSObject* jsobj = JSVAL_TO_OBJECT(*rval);
- if (jsobj && !js::GetObjectParent(jsobj))
- NS_ASSERTION(js::GetObjectClass(jsobj)->flags & JSCLASS_IS_GLOBAL,
- "Why did we recreate this wrapper?");
-#endif
-
- return true;
-}
-
-JSBool
-QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
-{
- JS::Value thisv = JS_THIS(cx, vp);
- if (thisv == JSVAL_NULL)
- return false;
-
- // Get the object. It might be a security wrapper, in which case we do a checked
- // unwrap.
- JSObject* origObj = JSVAL_TO_OBJECT(thisv);
- JSObject* obj = js::UnwrapObjectChecked(cx, origObj);
- if (!obj)
- return false;
-
- nsISupports* native;
- if (!UnwrapDOMObjectToISupports(obj, native)) {
- return Throw<true>(cx, NS_ERROR_FAILURE);
- }
-
- if (argc < 1) {
- return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
- }
-
- JS::Value* argv = JS_ARGV(cx, vp);
- if (!argv[0].isObject()) {
- return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
- }
-
- nsIJSIID* iid;
- xpc_qsSelfRef iidRef;
- if (NS_FAILED(xpc_qsUnwrapArg<nsIJSIID>(cx, argv[0], &iid, &iidRef.ptr,
- &argv[0]))) {
- return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
- }
- MOZ_ASSERT(iid);
-
- if (iid->GetID()->Equals(NS_GET_IID(nsIClassInfo))) {
- nsresult rv;
- nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(native, &rv);
- if (NS_FAILED(rv)) {
- return Throw<true>(cx, rv);
- }
-
- return WrapObject(cx, origObj, ci, &NS_GET_IID(nsIClassInfo), vp);
- }
-
- // Lie, otherwise we need to check classinfo or QI
- *vp = thisv;
- return true;
-}
-
-JSBool
-ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp)
-{
- return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
-}
-
-bool
-XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
- JSPropertyDescriptor* desc,
- // And the things we need to determine the descriptor
- Prefable<JSFunctionSpec>* methods,
- jsid* methodIds,
- JSFunctionSpec* methodSpecs,
- size_t methodCount,
- Prefable<JSPropertySpec>* attributes,
- jsid* attributeIds,
- JSPropertySpec* attributeSpecs,
- size_t attributeCount,
- Prefable<ConstantSpec>* constants,
- jsid* constantIds,
- ConstantSpec* constantSpecs,
- size_t constantCount)
-{
- for (size_t prefIdx = 0; prefIdx < methodCount; ++prefIdx) {
- MOZ_ASSERT(methods[prefIdx].specs);
- if (methods[prefIdx].enabled) {
- // Set i to be the index into our full list of ids/specs that we're
- // looking at now.
- size_t i = methods[prefIdx].specs - methodSpecs;
- for ( ; methodIds[i] != JSID_VOID; ++i) {
- if (id == methodIds[i]) {
- JSFunction *fun = JS_NewFunctionById(cx, methodSpecs[i].call.op,
- methodSpecs[i].nargs, 0,
- wrapper, id);
- if (!fun) {
- return false;
- }
- SET_JITINFO(fun, methodSpecs[i].call.info);
- JSObject *funobj = JS_GetFunctionObject(fun);
- desc->value.setObject(*funobj);
- desc->attrs = methodSpecs[i].flags;
- desc->obj = wrapper;
- desc->setter = nullptr;
- desc->getter = nullptr;
- return true;
- }
- }
- }
- }
-
- for (size_t prefIdx = 0; prefIdx < attributeCount; ++prefIdx) {
- MOZ_ASSERT(attributes[prefIdx].specs);
- if (attributes[prefIdx].enabled) {
- // Set i to be the index into our full list of ids/specs that we're
- // looking at now.
- size_t i = attributes[prefIdx].specs - attributeSpecs;
- for ( ; attributeIds[i] != JSID_VOID; ++i) {
- if (id == attributeIds[i]) {
- // Because of centralization, we need to make sure we fault in the
- // JitInfos as well. At present, until the JSAPI changes, the easiest
- // way to do this is wrap them up as functions ourselves.
- desc->attrs = attributeSpecs[i].flags & ~JSPROP_NATIVE_ACCESSORS;
- // They all have getters, so we can just make it.
- JSObject *global = JS_GetGlobalForObject(cx, wrapper);
- JSFunction *fun = JS_NewFunction(cx, (JSNative)attributeSpecs[i].getter.op,
- 0, 0, global, NULL);
- if (!fun)
- return false;
- SET_JITINFO(fun, attributeSpecs[i].getter.info);
- JSObject *funobj = JS_GetFunctionObject(fun);
- desc->getter = js::CastAsJSPropertyOp(funobj);
- desc->attrs |= JSPROP_GETTER;
- if (attributeSpecs[i].setter.op) {
- // We have a setter! Make it.
- fun = JS_NewFunction(cx, (JSNative)attributeSpecs[i].setter.op,
- 1, 0, global, NULL);
- if (!fun)
- return false;
- SET_JITINFO(fun, attributeSpecs[i].setter.info);
- funobj = JS_GetFunctionObject(fun);
- desc->setter = js::CastAsJSStrictPropertyOp(funobj);
- desc->attrs |= JSPROP_SETTER;
- } else {
- desc->setter = NULL;
- }
- desc->obj = wrapper;
- return true;
- }
- }
- }
- }
-
- for (size_t prefIdx = 0; prefIdx < constantCount; ++prefIdx) {
- MOZ_ASSERT(constants[prefIdx].specs);
- if (constants[prefIdx].enabled) {
- // Set i to be the index into our full list of ids/specs that we're
- // looking at now.
- size_t i = constants[prefIdx].specs - constantSpecs;
- for ( ; constantIds[i] != JSID_VOID; ++i) {
- if (id == constantIds[i]) {
- desc->attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
- desc->obj = wrapper;
- desc->value = constantSpecs[i].value;
- return true;
- }
- }
- }
- }
-
- return true;
-}
-
-bool
-XrayEnumerateProperties(JS::AutoIdVector& props,
- Prefable<JSFunctionSpec>* methods,
- jsid* methodIds,
- JSFunctionSpec* methodSpecs,
- size_t methodCount,
- Prefable<JSPropertySpec>* attributes,
- jsid* attributeIds,
- JSPropertySpec* attributeSpecs,
- size_t attributeCount,
- Prefable<ConstantSpec>* constants,
- jsid* constantIds,
- ConstantSpec* constantSpecs,
- size_t constantCount)
-{
- for (size_t prefIdx = 0; prefIdx < methodCount; ++prefIdx) {
- MOZ_ASSERT(methods[prefIdx].specs);
- if (methods[prefIdx].enabled) {
- // Set i to be the index into our full list of ids/specs that we're
- // looking at now.
- size_t i = methods[prefIdx].specs - methodSpecs;
- for ( ; methodIds[i] != JSID_VOID; ++i) {
- if ((methodSpecs[i].flags & JSPROP_ENUMERATE) &&
- !props.append(methodIds[i])) {
- return false;
- }
- }
- }
- }
-
- for (size_t prefIdx = 0; prefIdx < attributeCount; ++prefIdx) {
- MOZ_ASSERT(attributes[prefIdx].specs);
- if (attributes[prefIdx].enabled) {
- // Set i to be the index into our full list of ids/specs that we're
- // looking at now.
- size_t i = attributes[prefIdx].specs - attributeSpecs;
- for ( ; attributeIds[i] != JSID_VOID; ++i) {
- if ((attributeSpecs[i].flags & JSPROP_ENUMERATE) &&
- !props.append(attributeIds[i])) {
- return false;
- }
- }
- }
- }
-
- for (size_t prefIdx = 0; prefIdx < constantCount; ++prefIdx) {
- MOZ_ASSERT(constants[prefIdx].specs);
- if (constants[prefIdx].enabled) {
- // Set i to be the index into our full list of ids/specs that we're
- // looking at now.
- size_t i = constants[prefIdx].specs - constantSpecs;
- for ( ; constantIds[i] != JSID_VOID; ++i) {
- if (!props.append(constantIds[i])) {
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
-bool
-GetPropertyOnPrototype(JSContext* cx, JSObject* proxy, jsid id, bool* found,
- JS::Value* vp)
-{
- JSObject* proto;
- if (!js::GetObjectProto(cx, proxy, &proto)) {
- return false;
- }
- if (!proto) {
- *found = false;
- return true;
- }
-
- JSBool hasProp;
- if (!JS_HasPropertyById(cx, proto, id, &hasProp)) {
- return false;
- }
-
- *found = hasProp;
- if (!hasProp || !vp) {
- return true;
- }
-
- return JS_ForwardGetPropertyTo(cx, proto, id, proxy, vp);
-}
-
-bool
-HasPropertyOnPrototype(JSContext* cx, JSObject* proxy, DOMProxyHandler* handler,
- jsid id)
-{
- Maybe<JSAutoCompartment> ac;
- if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
- proxy = js::UnwrapObject(proxy);
- ac.construct(cx, proxy);
- }
- MOZ_ASSERT(js::IsProxy(proxy) && js::GetProxyHandler(proxy) == handler);
-
- bool found;
- // We ignore an error from GetPropertyOnPrototype.
- return !GetPropertyOnPrototype(cx, proxy, id, &found, NULL) || found;
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/src/components/script/dom/bindings/codegen/BindingUtils.h b/src/components/script/dom/bindings/codegen/BindingUtils.h
deleted file mode 100644
index ee9d6c3691c..00000000000
--- a/src/components/script/dom/bindings/codegen/BindingUtils.h
+++ /dev/null
@@ -1,1151 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
-/* 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/. */
-
-#ifndef mozilla_dom_BindingUtils_h__
-#define mozilla_dom_BindingUtils_h__
-
-#include "mozilla/dom/DOMJSClass.h"
-#include "mozilla/dom/DOMJSProxyHandler.h"
-#include "mozilla/dom/workers/Workers.h"
-#include "mozilla/ErrorResult.h"
-
-#include "jsapi.h"
-#include "jsfriendapi.h"
-#include "jswrapper.h"
-
-#include "nsIXPConnect.h"
-#include "qsObjectHelper.h"
-#include "xpcpublic.h"
-#include "nsTraceRefcnt.h"
-#include "nsWrapperCacheInlines.h"
-#include "mozilla/Likely.h"
-
-// nsGlobalWindow implements nsWrapperCache, but doesn't always use it. Don't
-// try to use it without fixing that first.
-class nsGlobalWindow;
-
-namespace mozilla {
-namespace dom {
-
-enum ErrNum {
-#define MSG_DEF(_name, _argc, _str) \
- _name,
-#include "mozilla/dom/Errors.msg"
-#undef MSG_DEF
- Err_Limit
-};
-
-bool
-ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...);
-
-template<bool mainThread>
-inline bool
-Throw(JSContext* cx, nsresult rv)
-{
- using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
-
- // XXX Introduce exception machinery.
- if (mainThread) {
- xpc::Throw(cx, rv);
- } else {
- if (!JS_IsExceptionPending(cx)) {
- ThrowDOMExceptionForNSResult(cx, rv);
- }
- }
- return false;
-}
-
-template<bool mainThread>
-inline bool
-ThrowMethodFailedWithDetails(JSContext* cx, const ErrorResult& rv,
- const char* /* ifaceName */,
- const char* /* memberName */)
-{
- return Throw<mainThread>(cx, rv.ErrorCode());
-}
-
-inline bool
-IsDOMClass(const JSClass* clasp)
-{
- return clasp->flags & JSCLASS_IS_DOMJSCLASS;
-}
-
-inline bool
-IsDOMClass(const js::Class* clasp)
-{
- return IsDOMClass(Jsvalify(clasp));
-}
-
-// It's ok for eRegularDOMObject and eProxyDOMObject to be the same, but
-// eNonDOMObject should always be different from the other two. This enum
-// shouldn't be used to differentiate between non-proxy and proxy bindings.
-enum DOMObjectSlot {
- eNonDOMObject = -1,
- eRegularDOMObject = DOM_OBJECT_SLOT,
- eProxyDOMObject = DOM_PROXY_OBJECT_SLOT
-};
-
-template <class T>
-inline T*
-UnwrapDOMObject(JSObject* obj, DOMObjectSlot slot)
-{
- MOZ_ASSERT(slot != eNonDOMObject,
- "Don't pass non-DOM objects to this function");
-
-#ifdef DEBUG
- if (IsDOMClass(js::GetObjectClass(obj))) {
- MOZ_ASSERT(slot == eRegularDOMObject);
- } else {
- MOZ_ASSERT(js::IsObjectProxyClass(js::GetObjectClass(obj)) ||
- js::IsFunctionProxyClass(js::GetObjectClass(obj)));
- MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
- MOZ_ASSERT(IsNewProxyBinding(js::GetProxyHandler(obj)));
- MOZ_ASSERT(slot == eProxyDOMObject);
- }
-#endif
-
- JS::Value val = js::GetReservedSlot(obj, slot);
- // XXXbz/khuey worker code tries to unwrap interface objects (which have
- // nothing here). That needs to stop.
- // XXX We don't null-check UnwrapObject's result; aren't we going to crash
- // anyway?
- if (val.isUndefined()) {
- return NULL;
- }
-
- return static_cast<T*>(val.toPrivate());
-}
-
-// Only use this with a new DOM binding object (either proxy or regular).
-inline const DOMClass*
-GetDOMClass(JSObject* obj)
-{
- js::Class* clasp = js::GetObjectClass(obj);
- if (IsDOMClass(clasp)) {
- return &DOMJSClass::FromJSClass(clasp)->mClass;
- }
-
- js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
- MOZ_ASSERT(handler->family() == ProxyFamily());
- MOZ_ASSERT(IsNewProxyBinding(handler));
- return &static_cast<DOMProxyHandler*>(handler)->mClass;
-}
-
-inline DOMObjectSlot
-GetDOMClass(JSObject* obj, const DOMClass*& result)
-{
- js::Class* clasp = js::GetObjectClass(obj);
- if (IsDOMClass(clasp)) {
- result = &DOMJSClass::FromJSClass(clasp)->mClass;
- return eRegularDOMObject;
- }
-
- if (js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) {
- js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
- if (handler->family() == ProxyFamily() && IsNewProxyBinding(handler)) {
- result = &static_cast<DOMProxyHandler*>(handler)->mClass;
- return eProxyDOMObject;
- }
- }
-
- return eNonDOMObject;
-}
-
-inline bool
-UnwrapDOMObjectToISupports(JSObject* obj, nsISupports*& result)
-{
- const DOMClass* clasp;
- DOMObjectSlot slot = GetDOMClass(obj, clasp);
- if (slot == eNonDOMObject || !clasp->mDOMObjectIsISupports) {
- return false;
- }
-
- result = UnwrapDOMObject<nsISupports>(obj, slot);
- return true;
-}
-
-inline bool
-IsDOMObject(JSObject* obj)
-{
- js::Class* clasp = js::GetObjectClass(obj);
- return IsDOMClass(clasp) ||
- ((js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) &&
- (js::GetProxyHandler(obj)->family() == ProxyFamily() &&
- IsNewProxyBinding(js::GetProxyHandler(obj))));
-}
-
-// Some callers don't want to set an exception when unwrapping fails
-// (for example, overload resolution uses unwrapping to tell what sort
-// of thing it's looking at).
-// U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
-template <prototypes::ID PrototypeID, class T, typename U>
-inline nsresult
-UnwrapObject(JSContext* cx, JSObject* obj, U& value)
-{
- /* First check to see whether we have a DOM object */
- const DOMClass* domClass;
- DOMObjectSlot slot = GetDOMClass(obj, domClass);
- if (slot == eNonDOMObject) {
- /* Maybe we have a security wrapper or outer window? */
- if (!js::IsWrapper(obj)) {
- /* Not a DOM object, not a wrapper, just bail */
- return NS_ERROR_XPC_BAD_CONVERT_JS;
- }
-
- obj = xpc::Unwrap(cx, obj, false);
- if (!obj) {
- return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
- }
- MOZ_ASSERT(!js::IsWrapper(obj));
- slot = GetDOMClass(obj, domClass);
- if (slot == eNonDOMObject) {
- /* We don't have a DOM object */
- return NS_ERROR_XPC_BAD_CONVERT_JS;
- }
- }
-
- /* This object is a DOM object. Double-check that it is safely
- castable to T by checking whether it claims to inherit from the
- class identified by protoID. */
- if (domClass->mInterfaceChain[PrototypeTraits<PrototypeID>::Depth] ==
- PrototypeID) {
- value = UnwrapDOMObject<T>(obj, slot);
- return NS_OK;
- }
-
- /* It's the wrong sort of DOM object */
- return NS_ERROR_XPC_BAD_CONVERT_JS;
-}
-
-inline bool
-IsArrayLike(JSContext* cx, JSObject* obj)
-{
- MOZ_ASSERT(obj);
- // For simplicity, check for security wrappers up front. In case we
- // have a security wrapper, don't forget to enter the compartment of
- // the underlying object after unwrapping.
- Maybe<JSAutoCompartment> ac;
- if (js::IsWrapper(obj)) {
- obj = xpc::Unwrap(cx, obj, false);
- if (!obj) {
- // Let's say it's not
- return false;
- }
-
- ac.construct(cx, obj);
- }
-
- // XXXbz need to detect platform objects (including listbinding
- // ones) with indexGetters here!
- return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj, cx);
-}
-
-inline bool
-IsPlatformObject(JSContext* cx, JSObject* obj)
-{
- // XXXbz Should be treating list-binding objects as platform objects
- // too? The one consumer so far wants non-array-like platform
- // objects, so listbindings that have an indexGetter should test
- // false from here. Maybe this function should have a different
- // name?
- MOZ_ASSERT(obj);
- // Fast-path the common case
- JSClass* clasp = js::GetObjectJSClass(obj);
- if (IsDOMClass(clasp)) {
- return true;
- }
- // Now for simplicity check for security wrappers before anything else
- if (js::IsWrapper(obj)) {
- obj = xpc::Unwrap(cx, obj, false);
- if (!obj) {
- // Let's say it's not
- return false;
- }
- clasp = js::GetObjectJSClass(obj);
- }
- return IS_WRAPPER_CLASS(js::Valueify(clasp)) || IsDOMClass(clasp) ||
- JS_IsArrayBufferObject(obj, cx);
-}
-
-// U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
-template <class T, typename U>
-inline nsresult
-UnwrapObject(JSContext* cx, JSObject* obj, U& value)
-{
- return UnwrapObject<static_cast<prototypes::ID>(
- PrototypeIDMap<T>::PrototypeID), T>(cx, obj, value);
-}
-
-const size_t kProtoOrIfaceCacheCount =
- prototypes::id::_ID_Count + constructors::id::_ID_Count;
-
-inline void
-AllocateProtoOrIfaceCache(JSObject* obj)
-{
- MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
- MOZ_ASSERT(js::GetReservedSlot(obj, DOM_PROTOTYPE_SLOT).isUndefined());
-
- // Important: The () at the end ensure zero-initialization
- JSObject** protoOrIfaceArray = new JSObject*[kProtoOrIfaceCacheCount]();
-
- js::SetReservedSlot(obj, DOM_PROTOTYPE_SLOT,
- JS::PrivateValue(protoOrIfaceArray));
-}
-
-inline void
-TraceProtoOrIfaceCache(JSTracer* trc, JSObject* obj)
-{
- MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
-
- if (!HasProtoOrIfaceArray(obj))
- return;
- JSObject** protoOrIfaceArray = GetProtoOrIfaceArray(obj);
- for (size_t i = 0; i < kProtoOrIfaceCacheCount; ++i) {
- JSObject* proto = protoOrIfaceArray[i];
- if (proto) {
- JS_CALL_OBJECT_TRACER(trc, proto, "protoOrIfaceArray[i]");
- }
- }
-}
-
-inline void
-DestroyProtoOrIfaceCache(JSObject* obj)
-{
- MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
-
- JSObject** protoOrIfaceArray = GetProtoOrIfaceArray(obj);
-
- delete [] protoOrIfaceArray;
-}
-
-struct ConstantSpec
-{
- const char* name;
- JS::Value value;
-};
-
-/**
- * Add constants to an object.
- */
-bool
-DefineConstants(JSContext* cx, JSObject* obj, ConstantSpec* cs);
-
-template<typename T>
-struct Prefable {
- // A boolean indicating whether this set of specs is enabled
- bool enabled;
- // Array of specs, terminated in whatever way is customary for T.
- // Null to indicate a end-of-array for Prefable, when such an
- // indicator is needed.
- T* specs;
-};
-
-/*
- * Create a DOM interface object (if constructorClass is non-null) and/or a
- * DOM interface prototype object (if protoClass is non-null).
- *
- * global is used as the parent of the interface object and the interface
- * prototype object
- * receiver is the object on which we need to define the interface object as a
- * property
- * protoProto is the prototype to use for the interface prototype object.
- * protoClass is the JSClass to use for the interface prototype object.
- * This is null if we should not create an interface prototype
- * object.
- * constructorClass is the JSClass to use for the interface object.
- * This is null if we should not create an interface object or
- * if it should be a function object.
- * constructor is the JSNative to use as a constructor. If this is non-null, it
- * should be used as a JSNative to back the interface object, which
- * should be a Function. If this is null, then we should create an
- * object of constructorClass, unless that's also null, in which
- * case we should not create an interface object at all.
- * ctorNargs is the length of the constructor function; 0 if no constructor
- * instanceClass is the JSClass of instance objects for this class. This can
- * be null if this is not a concrete proto.
- * methods and properties are to be defined on the interface prototype object;
- * these arguments are allowed to be null if there are no
- * methods or properties respectively.
- * constants are to be defined on the interface object and on the interface
- * prototype object; allowed to be null if there are no constants.
- * staticMethods are to be defined on the interface object; allowed to be null
- * if there are no static methods.
- *
- * At least one of protoClass and constructorClass should be non-null.
- * If constructorClass is non-null, the resulting interface object will be
- * defined on the given global with property name |name|, which must also be
- * non-null.
- *
- * returns the interface prototype object if protoClass is non-null, else it
- * returns the interface object.
- */
-JSObject*
-CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* receiver,
- JSObject* protoProto, JSClass* protoClass,
- JSClass* constructorClass, JSNative constructor,
- unsigned ctorNargs, const DOMClass* domClass,
- Prefable<JSFunctionSpec>* methods,
- Prefable<JSPropertySpec>* properties,
- Prefable<ConstantSpec>* constants,
- Prefable<JSFunctionSpec>* staticMethods, const char* name);
-
-template <class T>
-inline bool
-WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp)
-{
- JSObject* obj = value->GetWrapper();
- if (obj && js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) {
- *vp = JS::ObjectValue(*obj);
- return true;
- }
-
- if (!obj) {
- bool triedToWrap;
- obj = value->WrapObject(cx, scope, &triedToWrap);
- if (!obj) {
- // At this point, obj is null, so just return false. We could
- // try to communicate triedToWrap to the caller, but in practice
- // callers seem to be testing JS_IsExceptionPending(cx) to
- // figure out whether WrapObject() threw instead.
- return false;
- }
- }
-
- // When called via XrayWrapper, we end up here while running in the
- // chrome compartment. But the obj we have would be created in
- // whatever the content compartment is. So at this point we need to
- // make sure it's correctly wrapped for the compartment of |scope|.
- // cx should already be in the compartment of |scope| here.
- MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
- *vp = JS::ObjectValue(*obj);
- return JS_WrapValue(cx, vp);
-}
-
-// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
-template <template <typename> class SmartPtr, class T>
-inline bool
-WrapNewBindingObject(JSContext* cx, JSObject* scope, const SmartPtr<T>& value,
- JS::Value* vp)
-{
- return WrapNewBindingObject(cx, scope, value.get(), vp);
-}
-
-template <class T>
-inline bool
-WrapNewBindingNonWrapperCachedObject(JSContext* cx, JSObject* scope, T* value,
- JS::Value* vp)
-{
- // We try to wrap in the compartment of the underlying object of "scope"
- JSObject* obj;
- {
- // scope for the JSAutoCompartment so that we restore the compartment
- // before we call JS_WrapValue.
- Maybe<JSAutoCompartment> ac;
- if (js::IsWrapper(scope)) {
- scope = xpc::Unwrap(cx, scope, false);
- if (!scope)
- return false;
- ac.construct(cx, scope);
- }
-
- obj = value->WrapObject(cx, scope);
- }
-
- // We can end up here in all sorts of compartments, per above. Make
- // sure to JS_WrapValue!
- *vp = JS::ObjectValue(*obj);
- return JS_WrapValue(cx, vp);
-}
-
-// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
-template <template <typename> class SmartPtr, typename T>
-inline bool
-WrapNewBindingNonWrapperCachedObject(JSContext* cx, JSObject* scope,
- const SmartPtr<T>& value, JS::Value* vp)
-{
- return WrapNewBindingNonWrapperCachedObject(cx, scope, value.get(), vp);
-}
-
-/**
- * A method to handle new-binding wrap failure, by possibly falling back to
- * wrapping as a non-new-binding object.
- */
-bool
-DoHandleNewBindingWrappingFailure(JSContext* cx, JSObject* scope,
- nsISupports* value, JS::Value* vp);
-
-/**
- * An easy way to call the above when you have a value which
- * multiply-inherits from nsISupports.
- */
-template <class T>
-bool
-HandleNewBindingWrappingFailure(JSContext* cx, JSObject* scope, T* value,
- JS::Value* vp)
-{
- nsCOMPtr<nsISupports> val;
- CallQueryInterface(value, getter_AddRefs(val));
- return DoHandleNewBindingWrappingFailure(cx, scope, val, vp);
-}
-
-// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
-template <template <typename> class SmartPtr, class T>
-MOZ_ALWAYS_INLINE bool
-HandleNewBindingWrappingFailure(JSContext* cx, JSObject* scope,
- const SmartPtr<T>& value, JS::Value* vp)
-{
- return HandleNewBindingWrappingFailure(cx, scope, value.get(), vp);
-}
-
-struct EnumEntry {
- const char* value;
- size_t length;
-};
-
-template<bool Fatal>
-inline bool
-EnumValueNotFound(JSContext* cx, const jschar* chars, size_t length,
- const char* type)
-{
- return false;
-}
-
-template<>
-inline bool
-EnumValueNotFound<false>(JSContext* cx, const jschar* chars, size_t length,
- const char* type)
-{
- // TODO: Log a warning to the console.
- return true;
-}
-
-template<>
-inline bool
-EnumValueNotFound<true>(JSContext* cx, const jschar* chars, size_t length,
- const char* type)
-{
- NS_LossyConvertUTF16toASCII deflated(static_cast<const PRUnichar*>(chars),
- length);
- return ThrowErrorMessage(cx, MSG_INVALID_ENUM_VALUE, deflated.get(), type);
-}
-
-
-template<bool InvalidValueFatal>
-inline int
-FindEnumStringIndex(JSContext* cx, JS::Value v, const EnumEntry* values,
- const char* type, bool* ok)
-{
- // JS_StringEqualsAscii is slow as molasses, so don't use it here.
- JSString* str = JS_ValueToString(cx, v);
- if (!str) {
- *ok = false;
- return 0;
- }
- JS::Anchor<JSString*> anchor(str);
- size_t length;
- const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
- if (!chars) {
- *ok = false;
- return 0;
- }
- int i = 0;
- for (const EnumEntry* value = values; value->value; ++value, ++i) {
- if (length != value->length) {
- continue;
- }
-
- bool equal = true;
- const char* val = value->value;
- for (size_t j = 0; j != length; ++j) {
- if (unsigned(val[j]) != unsigned(chars[j])) {
- equal = false;
- break;
- }
- }
-
- if (equal) {
- *ok = true;
- return i;
- }
- }
-
- *ok = EnumValueNotFound<InvalidValueFatal>(cx, chars, length, type);
- return -1;
-}
-
-inline nsWrapperCache*
-GetWrapperCache(nsWrapperCache* cache)
-{
- return cache;
-}
-
-inline nsWrapperCache*
-GetWrapperCache(nsGlobalWindow* not_allowed);
-
-inline nsWrapperCache*
-GetWrapperCache(void* p)
-{
- return NULL;
-}
-
-struct ParentObject {
- template<class T>
- ParentObject(T* aObject) :
- mObject(aObject),
- mWrapperCache(GetWrapperCache(aObject))
- {}
-
- template<class T, template<typename> class SmartPtr>
- ParentObject(const SmartPtr<T>& aObject) :
- mObject(aObject.get()),
- mWrapperCache(GetWrapperCache(aObject.get()))
- {}
-
- ParentObject(nsISupports* aObject, nsWrapperCache* aCache) :
- mObject(aObject),
- mWrapperCache(aCache)
- {}
-
- nsISupports* const mObject;
- nsWrapperCache* const mWrapperCache;
-};
-
-inline nsWrapperCache*
-GetWrapperCache(const ParentObject& aParentObject)
-{
- return aParentObject.mWrapperCache;
-}
-
-template<class T>
-inline nsISupports*
-GetParentPointer(T* aObject)
-{
- return ToSupports(aObject);
-}
-
-inline nsISupports*
-GetParentPointer(const ParentObject& aObject)
-{
- return ToSupports(aObject.mObject);
-}
-
-template<class T>
-inline void
-ClearWrapper(T* p, nsWrapperCache* cache)
-{
- cache->ClearWrapper();
-}
-
-template<class T>
-inline void
-ClearWrapper(T* p, void*)
-{
- nsWrapperCache* cache;
- CallQueryInterface(p, &cache);
- ClearWrapper(p, cache);
-}
-
-// Can only be called with the immediate prototype of the instance object. Can
-// only be called on the prototype of an object known to be a DOM instance.
-JSBool
-InstanceClassHasProtoAtDepth(JSHandleObject protoObject, uint32_t protoID,
- uint32_t depth);
-
-// Only set allowNativeWrapper to false if you really know you need it, if in
-// doubt use true. Setting it to false disables security wrappers.
-bool
-XPCOMObjectToJsval(JSContext* cx, JSObject* scope, xpcObjectHelper &helper,
- const nsIID* iid, bool allowNativeWrapper, JS::Value* rval);
-
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JSObject* scope, T* p, nsWrapperCache* cache,
- const nsIID* iid, JS::Value* vp)
-{
- if (xpc_FastGetCachedWrapper(cache, scope, vp))
- return true;
- qsObjectHelper helper(p, cache);
- return XPCOMObjectToJsval(cx, scope, helper, iid, true, vp);
-}
-
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JSObject* scope, T* p, const nsIID* iid,
- JS::Value* vp)
-{
- return WrapObject(cx, scope, p, GetWrapperCache(p), iid, vp);
-}
-
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JSObject* scope, T* p, JS::Value* vp)
-{
- return WrapObject(cx, scope, p, NULL, vp);
-}
-
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JSObject* scope, nsCOMPtr<T> &p, const nsIID* iid,
- JS::Value* vp)
-{
- return WrapObject(cx, scope, p.get(), iid, vp);
-}
-
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JSObject* scope, nsCOMPtr<T> &p, JS::Value* vp)
-{
- return WrapObject(cx, scope, p, NULL, vp);
-}
-
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JSObject* scope, nsRefPtr<T> &p, const nsIID* iid,
- JS::Value* vp)
-{
- return WrapObject(cx, scope, p.get(), iid, vp);
-}
-
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JSObject* scope, nsRefPtr<T> &p, JS::Value* vp)
-{
- return WrapObject(cx, scope, p, NULL, vp);
-}
-
-template<>
-inline bool
-WrapObject<JSObject>(JSContext* cx, JSObject* scope, JSObject* p, JS::Value* vp)
-{
- vp->setObjectOrNull(p);
- return true;
-}
-
-template<typename T>
-static inline JSObject*
-WrapNativeParent(JSContext* cx, JSObject* scope, const T& p)
-{
- if (!GetParentPointer(p))
- return scope;
-
- nsWrapperCache* cache = GetWrapperCache(p);
- JSObject* obj;
- if (cache && (obj = cache->GetWrapper())) {
-#ifdef DEBUG
- qsObjectHelper helper(GetParentPointer(p), cache);
- JS::Value debugVal;
-
- bool ok = XPCOMObjectToJsval(cx, scope, helper, NULL, false, &debugVal);
- NS_ASSERTION(ok && JSVAL_TO_OBJECT(debugVal) == obj,
- "Unexpected object in nsWrapperCache");
-#endif
- return obj;
- }
-
- qsObjectHelper helper(GetParentPointer(p), cache);
- JS::Value v;
- return XPCOMObjectToJsval(cx, scope, helper, NULL, false, &v) ?
- JSVAL_TO_OBJECT(v) :
- NULL;
-}
-
-static inline bool
-InternJSString(JSContext* cx, jsid& id, const char* chars)
-{
- if (JSString *str = ::JS_InternString(cx, chars)) {
- id = INTERNED_STRING_TO_JSID(cx, str);
- return true;
- }
- return false;
-}
-
-// Spec needs a name property
-template <typename Spec>
-static bool
-InitIds(JSContext* cx, Prefable<Spec>* prefableSpecs, jsid* ids)
-{
- MOZ_ASSERT(prefableSpecs);
- MOZ_ASSERT(prefableSpecs->specs);
- do {
- // We ignore whether the set of ids is enabled and just intern all the IDs,
- // because this is only done once per application runtime.
- Spec* spec = prefableSpecs->specs;
- do {
- if (!InternJSString(cx, *ids, spec->name)) {
- return false;
- }
- } while (++ids, (++spec)->name);
-
- // We ran out of ids for that pref. Put a JSID_VOID in on the id
- // corresponding to the list terminator for the pref.
- *ids = JSID_VOID;
- ++ids;
- } while ((++prefableSpecs)->specs);
-
- return true;
-}
-
-JSBool
-QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp);
-JSBool
-ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
-
-bool
-GetPropertyOnPrototype(JSContext* cx, JSObject* proxy, jsid id, bool* found,
- JS::Value* vp);
-
-bool
-HasPropertyOnPrototype(JSContext* cx, JSObject* proxy, DOMProxyHandler* handler,
- jsid id);
-
-template<class T>
-class NonNull
-{
-public:
- NonNull()
-#ifdef DEBUG
- : inited(false)
-#endif
- {}
-
- operator T&() {
- MOZ_ASSERT(inited);
- MOZ_ASSERT(ptr, "NonNull<T> was set to null");
- return *ptr;
- }
-
- operator const T&() const {
- MOZ_ASSERT(inited);
- MOZ_ASSERT(ptr, "NonNull<T> was set to null");
- return *ptr;
- }
-
- void operator=(T* t) {
- ptr = t;
- MOZ_ASSERT(ptr);
-#ifdef DEBUG
- inited = true;
-#endif
- }
-
- template<typename U>
- void operator=(U* t) {
- ptr = t->ToAStringPtr();
- MOZ_ASSERT(ptr);
-#ifdef DEBUG
- inited = true;
-#endif
- }
-
- T** Slot() {
-#ifdef DEBUG
- inited = true;
-#endif
- return &ptr;
- }
-
-protected:
- T* ptr;
-#ifdef DEBUG
- bool inited;
-#endif
-};
-
-template<class T>
-class OwningNonNull
-{
-public:
- OwningNonNull()
-#ifdef DEBUG
- : inited(false)
-#endif
- {}
-
- operator T&() {
- MOZ_ASSERT(inited);
- MOZ_ASSERT(ptr, "OwningNonNull<T> was set to null");
- return *ptr;
- }
-
- void operator=(T* t) {
- init(t);
- }
-
- void operator=(const already_AddRefed<T>& t) {
- init(t);
- }
-
-protected:
- template<typename U>
- void init(U t) {
- ptr = t;
- MOZ_ASSERT(ptr);
-#ifdef DEBUG
- inited = true;
-#endif
- }
-
- nsRefPtr<T> ptr;
-#ifdef DEBUG
- bool inited;
-#endif
-};
-
-// A struct that has the same layout as an nsDependentString but much
-// faster constructor and destructor behavior
-struct FakeDependentString {
- FakeDependentString() :
- mFlags(nsDependentString::F_TERMINATED)
- {
- }
-
- void SetData(const nsDependentString::char_type* aData,
- nsDependentString::size_type aLength) {
- MOZ_ASSERT(mFlags == nsDependentString::F_TERMINATED);
- mData = aData;
- mLength = aLength;
- }
-
- void Truncate() {
- mData = nsDependentString::char_traits::sEmptyBuffer;
- mLength = 0;
- }
-
- void SetNull() {
- Truncate();
- mFlags |= nsDependentString::F_VOIDED;
- }
-
- const nsAString* ToAStringPtr() const {
- return reinterpret_cast<const nsDependentString*>(this);
- }
-
- nsAString* ToAStringPtr() {
- return reinterpret_cast<nsDependentString*>(this);
- }
-
- operator const nsAString& () const {
- return *reinterpret_cast<const nsDependentString*>(this);
- }
-
-private:
- const nsDependentString::char_type* mData;
- nsDependentString::size_type mLength;
- uint32_t mFlags;
-
- // A class to use for our static asserts to ensure our object layout
- // matches that of nsDependentString.
- class DependentStringAsserter;
- friend class DependentStringAsserter;
-
- class DepedentStringAsserter : public nsDependentString {
- public:
- static void StaticAsserts() {
- MOZ_STATIC_ASSERT(sizeof(FakeDependentString) == sizeof(nsDependentString),
- "Must have right object size");
- MOZ_STATIC_ASSERT(offsetof(FakeDependentString, mData) ==
- offsetof(DepedentStringAsserter, mData),
- "Offset of mData should match");
- MOZ_STATIC_ASSERT(offsetof(FakeDependentString, mLength) ==
- offsetof(DepedentStringAsserter, mLength),
- "Offset of mLength should match");
- MOZ_STATIC_ASSERT(offsetof(FakeDependentString, mFlags) ==
- offsetof(DepedentStringAsserter, mFlags),
- "Offset of mFlags should match");
- }
- };
-};
-
-enum StringificationBehavior {
- eStringify,
- eEmpty,
- eNull
-};
-
-// pval must not be null and must point to a rooted JS::Value
-static inline bool
-ConvertJSValueToString(JSContext* cx, const JS::Value& v, JS::Value* pval,
- StringificationBehavior nullBehavior,
- StringificationBehavior undefinedBehavior,
- FakeDependentString& result)
-{
- JSString *s;
- if (v.isString()) {
- s = v.toString();
- } else {
- StringificationBehavior behavior;
- if (v.isNull()) {
- behavior = nullBehavior;
- } else if (v.isUndefined()) {
- behavior = undefinedBehavior;
- } else {
- behavior = eStringify;
- }
-
- if (behavior != eStringify) {
- if (behavior == eEmpty) {
- result.Truncate();
- } else {
- result.SetNull();
- }
- return true;
- }
-
- s = JS_ValueToString(cx, v);
- if (!s) {
- return false;
- }
- pval->setString(s); // Root the new string.
- }
-
- size_t len;
- const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &len);
- if (!chars) {
- return false;
- }
-
- result.SetData(chars, len);
- return true;
-}
-
-// Class for representing optional arguments.
-template<typename T>
-class Optional {
-public:
- Optional() {}
-
- bool WasPassed() const {
- return !mImpl.empty();
- }
-
- void Construct() {
- mImpl.construct();
- }
-
- template <class T1, class T2>
- void Construct(const T1 &t1, const T2 &t2) {
- mImpl.construct(t1, t2);
- }
-
- const T& Value() const {
- return mImpl.ref();
- }
-
- T& Value() {
- return mImpl.ref();
- }
-
-private:
- // Forbid copy-construction and assignment
- Optional(const Optional& other) MOZ_DELETE;
- const Optional &operator=(const Optional &other) MOZ_DELETE;
-
- Maybe<T> mImpl;
-};
-
-// Specialization for strings.
-template<>
-class Optional<nsAString> {
-public:
- Optional() : mPassed(false) {}
-
- bool WasPassed() const {
- return mPassed;
- }
-
- void operator=(const nsAString* str) {
- MOZ_ASSERT(str);
- mStr = str;
- mPassed = true;
- }
-
- void operator=(const FakeDependentString* str) {
- MOZ_ASSERT(str);
- mStr = str->ToAStringPtr();
- mPassed = true;
- }
-
- const nsAString& Value() const {
- MOZ_ASSERT(WasPassed());
- return *mStr;
- }
-
-private:
- // Forbid copy-construction and assignment
- Optional(const Optional& other) MOZ_DELETE;
- const Optional &operator=(const Optional &other) MOZ_DELETE;
-
- bool mPassed;
- const nsAString* mStr;
-};
-
-// Class for representing sequences in arguments. We use an auto array that can
-// hold 16 elements, to avoid having to allocate in common cases. This needs to
-// be fallible because web content controls the length of the array, and can
-// easily try to create very large lengths.
-template<typename T>
-class Sequence : public AutoFallibleTArray<T, 16>
-{
-public:
- Sequence() : AutoFallibleTArray<T, 16>() {}
-};
-
-// Class for holding the type of members of a union. The union type has an enum
-// to keep track of which of its UnionMembers has been constructed.
-template<class T>
-class UnionMember {
- AlignedStorage2<T> storage;
-
-public:
- T& SetValue() {
- new (storage.addr()) T();
- return *storage.addr();
- }
- const T& Value() const {
- return *storage.addr();
- }
- void Destroy() {
- storage.addr()->~T();
- }
-};
-
-// Implementation of the bits that XrayWrapper needs
-bool
-XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
- JSPropertyDescriptor* desc,
- // And the things we need to determine the descriptor
- Prefable<JSFunctionSpec>* methods,
- jsid* methodIds,
- JSFunctionSpec* methodSpecs,
- size_t methodCount,
- Prefable<JSPropertySpec>* attributes,
- jsid* attributeIds,
- JSPropertySpec* attributeSpecs,
- size_t attributeCount,
- Prefable<ConstantSpec>* constants,
- jsid* constantIds,
- ConstantSpec* constantSpecs,
- size_t constantCount);
-
-bool
-XrayEnumerateProperties(JS::AutoIdVector& props,
- Prefable<JSFunctionSpec>* methods,
- jsid* methodIds,
- JSFunctionSpec* methodSpecs,
- size_t methodCount,
- Prefable<JSPropertySpec>* attributes,
- jsid* attributeIds,
- JSPropertySpec* attributeSpecs,
- size_t attributeCount,
- Prefable<ConstantSpec>* constants,
- jsid* constantIds,
- ConstantSpec* constantSpecs,
- size_t constantCount);
-
-} // namespace dom
-} // namespace mozilla
-
-#endif /* mozilla_dom_BindingUtils_h__ */
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf
deleted file mode 100644
index f8119bc71f5..00000000000
--- a/src/components/script/dom/bindings/codegen/Bindings.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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/.
-
-# DOM Bindings Configuration.
-#
-# The WebIDL interfaces are defined in dom/webidls. For each such interface,
-# there is a corresponding entry in the configuration table below.
-# The configuration table maps each interface name to a |descriptor|.
-#
-# Valid fields for all descriptors:
-# * createGlobal: True for global objects.
-# * outerObjectHook: string to use in place of default value for outerObject and thisObject
-# JS class hooks
-
-DOMInterfaces = {
-
-'EventListener': {
- 'nativeType': 'EventListenerBinding::EventListener',
-},
-'Window': {
- 'outerObjectHook': 'Some(bindings::utils::outerize_global)',
-},
-
-#FIXME(jdm): This should be 'register': False, but then we don't generate enum types
-'TestBinding': {},
-
-}
diff --git a/src/components/script/dom/bindings/codegen/Codegen.py b/src/components/script/dom/bindings/codegen/Codegen.py
deleted file mode 100644
index 6d2cc0bde36..00000000000
--- a/src/components/script/dom/bindings/codegen/Codegen.py
+++ /dev/null
@@ -1,5788 +0,0 @@
-# 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/.
-
-# Common codegen classes.
-
-import os
-import string
-import operator
-
-from WebIDL import *
-from Configuration import NoSuchDescriptorError
-
-AUTOGENERATED_WARNING_COMMENT = \
- "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
-ADDPROPERTY_HOOK_NAME = '_addProperty'
-FINALIZE_HOOK_NAME = '_finalize'
-TRACE_HOOK_NAME = '_trace'
-CONSTRUCT_HOOK_NAME = '_constructor'
-HASINSTANCE_HOOK_NAME = '_hasInstance'
-
-def replaceFileIfChanged(filename, newContents):
- """
- Read a copy of the old file, so that we don't touch it if it hasn't changed.
- Returns True if the file was updated, false otherwise.
- """
- oldFileContents = ""
- try:
- oldFile = open(filename, 'rb')
- oldFileContents = ''.join(oldFile.readlines())
- oldFile.close()
- except:
- pass
-
- if newContents == oldFileContents:
- return False
-
- f = open(filename, 'wb')
- f.write(newContents)
- f.close()
-
-def toStringBool(arg):
- return str(not not arg).lower()
-
-def toBindingNamespace(arg):
- return re.sub("((_workers)?$)", "Binding\\1", arg);
-
-class CGThing():
- """
- Abstract base class for things that spit out code.
- """
- def __init__(self):
- pass # Nothing for now
- def declare(self):
- """Produce code for a header file."""
- assert(False) # Override me!
- def define(self):
- """Produce code for a cpp file."""
- assert(False) # Override me!
-
-class CGNativePropertyHooks(CGThing):
- """
- Generate a NativePropertyHooks for a given descriptor
- """
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
- def declare(self):
- if self.descriptor.workers:
- return ""
- return "extern const NativePropertyHooks NativeHooks;\n"
- def define(self):
- if self.descriptor.workers:
- return ""
- if self.descriptor.concrete and self.descriptor.proxy:
- resolveOwnProperty = "ResolveOwnProperty"
- enumerateOwnProperties = "EnumerateOwnProperties"
- else:
- enumerateOwnProperties = resolveOwnProperty = "NULL"
- parent = self.descriptor.interface.parent
- parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::NativeHooks"
- if parent else 'NULL')
- return """
-const NativePropertyHooks NativeHooks = { %s, ResolveProperty, %s, EnumerateProperties, %s };
-""" % (resolveOwnProperty, enumerateOwnProperties, parentHooks)
-
-def DOMClass(descriptor):
- protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeChain]
- # Pad out the list to the right length with _ID_Count so we
- # guarantee that all the lists are the same length. _ID_Count
- # is never the ID of any prototype, so it's safe to use as
- # padding.
- protoList.extend(['prototypes::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList)))
- prototypeChainString = ', '.join(protoList)
- nativeHooks = "NULL" if descriptor.workers else "&NativeHooks"
- return """{
- { %s },
- %s, %s
-}""" % (prototypeChainString, toStringBool(descriptor.nativeIsISupports),
- nativeHooks)
-
-class CGDOMJSClass(CGThing):
- """
- Generate a DOMJSClass for a given descriptor
- """
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
- def declare(self):
- return "extern DOMJSClass Class;\n"
- def define(self):
- traceHook = TRACE_HOOK_NAME if self.descriptor.customTrace else 'NULL'
- return """
-DOMJSClass Class = {
- { "%s",
- JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
- %s, /* addProperty */
- JS_PropertyStub, /* delProperty */
- JS_PropertyStub, /* getProperty */
- JS_StrictPropertyStub, /* setProperty */
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- %s, /* finalize */
- NULL, /* checkAccess */
- NULL, /* call */
- NULL, /* hasInstance */
- NULL, /* construct */
- %s, /* trace */
- JSCLASS_NO_INTERNAL_MEMBERS
- },
- %s
-};
-""" % (self.descriptor.interface.identifier.name,
- ADDPROPERTY_HOOK_NAME if self.descriptor.concrete and not self.descriptor.workers and self.descriptor.wrapperCache else 'JS_PropertyStub',
- FINALIZE_HOOK_NAME, traceHook,
- CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
-
-class CGPrototypeJSClass(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
- def declare(self):
- # We're purely for internal consumption
- return ""
- def define(self):
- return """static JSClass PrototypeClass = {
- "%sPrototype",
- JSCLASS_HAS_RESERVED_SLOTS(1),
- JS_PropertyStub, /* addProperty */
- JS_PropertyStub, /* delProperty */
- JS_PropertyStub, /* getProperty */
- JS_StrictPropertyStub, /* setProperty */
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- NULL, /* finalize */
- NULL, /* checkAccess */
- NULL, /* call */
- NULL, /* hasInstance */
- NULL, /* construct */
- NULL, /* trace */
- JSCLASS_NO_INTERNAL_MEMBERS
-};
-""" % (self.descriptor.interface.identifier.name)
-
-class CGInterfaceObjectJSClass(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
- def declare(self):
- # We're purely for internal consumption
- return ""
- def define(self):
- if not self.descriptor.hasInstanceInterface:
- return ""
- ctorname = "NULL" if not self.descriptor.interface.ctor() else CONSTRUCT_HOOK_NAME
- hasinstance = HASINSTANCE_HOOK_NAME
- return """
-static JSClass InterfaceObjectClass = {
- "Function", 0,
- JS_PropertyStub, /* addProperty */
- JS_PropertyStub, /* delProperty */
- JS_PropertyStub, /* getProperty */
- JS_StrictPropertyStub, /* setProperty */
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- NULL, /* finalize */
- NULL, /* checkAccess */
- %s, /* call */
- %s, /* hasInstance */
- %s, /* construct */
- NULL, /* trace */
- JSCLASS_NO_INTERNAL_MEMBERS
-};
-""" % (ctorname, hasinstance, ctorname)
-
-class CGList(CGThing):
- """
- Generate code for a list of GCThings. Just concatenates them together, with
- an optional joiner string. "\n" is a common joiner.
- """
- def __init__(self, children, joiner=""):
- CGThing.__init__(self)
- self.children = children
- self.joiner = joiner
- def append(self, child):
- self.children.append(child)
- def prepend(self, child):
- self.children.insert(0, child)
- def join(self, generator):
- return self.joiner.join(filter(lambda s: len(s) > 0, (child for child in generator)))
- def declare(self):
- return self.join(child.declare() for child in self.children if child is not None)
- def define(self):
- return self.join(child.define() for child in self.children if child is not None)
-
-class CGGeneric(CGThing):
- """
- A class that spits out a fixed string into the codegen. Can spit out a
- separate string for the declaration too.
- """
- def __init__(self, define="", declare=""):
- self.declareText = declare
- self.defineText = define
- def declare(self):
- return self.declareText
- def define(self):
- return self.defineText
-
-# We'll want to insert the indent at the beginnings of lines, but we
-# don't want to indent empty lines. So only indent lines that have a
-# non-newline character on them.
-lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE)
-class CGIndenter(CGThing):
- """
- A class that takes another CGThing and generates code that indents that
- CGThing by some number of spaces. The default indent is two spaces.
- """
- def __init__(self, child, indentLevel=2, declareOnly=False):
- CGThing.__init__(self)
- self.child = child
- self.indent = " " * indentLevel
- self.declareOnly = declareOnly
- def declare(self):
- decl = self.child.declare()
- if decl is not "":
- return re.sub(lineStartDetector, self.indent, decl)
- else:
- return ""
- def define(self):
- defn = self.child.define()
- if defn is not "" and not self.declareOnly:
- return re.sub(lineStartDetector, self.indent, defn)
- else:
- return defn
-
-class CGWrapper(CGThing):
- """
- Generic CGThing that wraps other CGThings with pre and post text.
- """
- def __init__(self, child, pre="", post="", declarePre=None,
- declarePost=None, definePre=None, definePost=None,
- declareOnly=False, defineOnly=False, reindent=False):
- CGThing.__init__(self)
- self.child = child
- self.declarePre = declarePre or pre
- self.declarePost = declarePost or post
- self.definePre = definePre or pre
- self.definePost = definePost or post
- self.declareOnly = declareOnly
- self.defineOnly = defineOnly
- self.reindent = reindent
- def declare(self):
- if self.defineOnly:
- return ''
- decl = self.child.declare()
- if self.reindent:
- # We don't use lineStartDetector because we don't want to
- # insert whitespace at the beginning of our _first_ line.
- decl = stripTrailingWhitespace(
- decl.replace("\n", "\n" + (" " * len(self.declarePre))))
- return self.declarePre + decl + self.declarePost
- def define(self):
- if self.declareOnly:
- return ''
- defn = self.child.define()
- if self.reindent:
- # We don't use lineStartDetector because we don't want to
- # insert whitespace at the beginning of our _first_ line.
- defn = stripTrailingWhitespace(
- defn.replace("\n", "\n" + (" " * len(self.definePre))))
- return self.definePre + defn + self.definePost
-
-class CGIfWrapper(CGWrapper):
- def __init__(self, child, condition):
- pre = CGWrapper(CGGeneric(condition), pre="if (", post=") {\n",
- reindent=True)
- CGWrapper.__init__(self, CGIndenter(child), pre=pre.define(),
- post="\n}")
-
-class CGNamespace(CGWrapper):
- def __init__(self, namespace, child, declareOnly=False):
- pre = "namespace %s {\n" % namespace
- post = "} // namespace %s\n" % namespace
- CGWrapper.__init__(self, child, pre=pre, post=post,
- declareOnly=declareOnly)
- @staticmethod
- def build(namespaces, child, declareOnly=False):
- """
- Static helper method to build multiple wrapped namespaces.
- """
- if not namespaces:
- return CGWrapper(child, declareOnly=declareOnly)
- inner = CGNamespace.build(namespaces[1:], child, declareOnly=declareOnly)
- return CGNamespace(namespaces[0], inner, declareOnly=declareOnly)
-
-class CGIncludeGuard(CGWrapper):
- """
- Generates include guards for a header.
- """
- def __init__(self, prefix, child):
- """|prefix| is the filename without the extension."""
- define = 'mozilla_dom_%s_h__' % prefix
- CGWrapper.__init__(self, child,
- declarePre='#ifndef %s\n#define %s\n\n' % (define, define),
- declarePost='\n#endif // %s\n' % define)
-
-def getTypes(descriptor):
- """
- Get all argument and return types for all members of the descriptor
- """
- members = [m for m in descriptor.interface.members]
- if descriptor.interface.ctor():
- members.append(descriptor.interface.ctor())
- signatures = [s for m in members if m.isMethod() for s in m.signatures()]
- types = []
- for s in signatures:
- assert len(s) == 2
- (returnType, arguments) = s
- types.append(returnType)
- types.extend([a.type for a in arguments])
-
- types.extend(a.type for a in members if a.isAttr())
- return types
-
-class CGHeaders(CGWrapper):
- """
- Generates the appropriate include statements.
- """
- def __init__(self, descriptors, dictionaries, declareIncludes,
- defineIncludes, child):
- """
- Builds a set of includes to cover |descriptors|.
-
- Also includes the files in |declareIncludes| in the header
- file and the files in |defineIncludes| in the .cpp.
- """
-
- # Determine the filenames for which we need headers.
- interfaceDeps = [d.interface for d in descriptors]
- ancestors = []
- for iface in interfaceDeps:
- while iface.parent:
- ancestors.append(iface.parent)
- iface = iface.parent
- interfaceDeps.extend(ancestors)
- bindingIncludes = set(self.getDeclarationFilename(d) for d in interfaceDeps)
-
- # Grab all the implementation declaration files we need.
- implementationIncludes = set(d.headerFile for d in descriptors)
-
- # Now find all the things we'll need as arguments because we
- # need to wrap or unwrap them.
- bindingHeaders = set()
- for d in descriptors:
- types = getTypes(d)
- for dictionary in dictionaries:
- curDict = dictionary
- while curDict:
- types.extend([m.type for m in curDict.members])
- curDict = curDict.parent
-
- for t in types:
- if t.unroll().isUnion():
- # UnionConversions.h includes UnionTypes.h
- bindingHeaders.add("mozilla/dom/UnionConversions.h")
- elif t.unroll().isInterface():
- if t.unroll().isSpiderMonkeyInterface():
- bindingHeaders.add("jsfriendapi.h")
- bindingHeaders.add("mozilla/dom/TypedArray.h")
- else:
- typeDesc = d.getDescriptor(t.unroll().inner.identifier.name)
- if typeDesc is not None:
- implementationIncludes.add(typeDesc.headerFile)
- bindingHeaders.add(self.getDeclarationFilename(typeDesc.interface))
- elif t.unroll().isDictionary():
- bindingHeaders.add(self.getDeclarationFilename(t.unroll().inner))
-
- declareIncludes = set(declareIncludes)
- for d in dictionaries:
- if d.parent:
- declareIncludes.add(self.getDeclarationFilename(d.parent))
- bindingHeaders.add(self.getDeclarationFilename(d))
-
- # Let the machinery do its thing.
- def _includeString(includes):
- return ''.join(['#include "%s"\n' % i for i in includes]) + '\n'
- CGWrapper.__init__(self, child,
- declarePre=_includeString(sorted(declareIncludes)),
- definePre=_includeString(sorted(set(defineIncludes) |
- bindingIncludes |
- bindingHeaders |
- implementationIncludes)))
- @staticmethod
- def getDeclarationFilename(decl):
- # Use our local version of the header, not the exported one, so that
- # test bindings, which don't export, will work correctly.
- basename = os.path.basename(decl.filename())
- return basename.replace('.webidl', 'Binding.h')
-
-def SortedTuples(l):
- """
- Sort a list of tuples based on the first item in the tuple
- """
- return sorted(l, key=operator.itemgetter(0))
-
-def SortedDictValues(d):
- """
- Returns a list of values from the dict sorted by key.
- """
- # Create a list of tuples containing key and value, sorted on key.
- d = SortedTuples(d.items())
- # We're only interested in the values.
- return (i[1] for i in d)
-
-def UnionTypes(descriptors):
- """
- Returns a tuple containing a set of header filenames to include, a set of
- tuples containing a type declaration and a boolean if the type is a struct
- for member types of the unions and a CGList containing CGUnionStructs for
- every union.
- """
-
- # Now find all the things we'll need as arguments and return values because
- # we need to wrap or unwrap them.
- headers = set()
- declarations = set()
- unionStructs = dict()
- for d in descriptors:
- if d.interface.isExternal():
- continue
-
- for t in getTypes(d):
- t = t.unroll()
- if t.isUnion():
- name = str(t)
- if not name in unionStructs:
- unionStructs[name] = CGUnionStruct(t, d)
- for f in t.flatMemberTypes:
- f = f.unroll()
- if f.isInterface():
- if f.isSpiderMonkeyInterface():
- headers.add("jsfriendapi.h")
- headers.add("mozilla/dom/TypedArray.h")
- else:
- typeDesc = d.getDescriptor(f.inner.identifier.name)
- if typeDesc is not None:
- declarations.add((typeDesc.nativeType, False))
- elif f.isDictionary():
- declarations.add((f.inner.identifier.name, True))
-
- return (headers, declarations, CGList(SortedDictValues(unionStructs), "\n"))
-
-def UnionConversions(descriptors):
- """
- Returns a CGThing to declare all union argument conversion helper structs.
- """
- # Now find all the things we'll need as arguments because we
- # need to unwrap them.
- unionConversions = dict()
- for d in descriptors:
- if d.interface.isExternal():
- continue
-
- def addUnionTypes(type):
- if type.isUnion():
- type = type.unroll()
- name = str(type)
- if not name in unionConversions:
- unionConversions[name] = CGUnionConversionStruct(type, d)
-
- members = [m for m in d.interface.members]
- if d.interface.ctor():
- members.append(d.interface.ctor())
- signatures = [s for m in members if m.isMethod() for s in m.signatures()]
- for s in signatures:
- assert len(s) == 2
- (_, arguments) = s
- for a in arguments:
- addUnionTypes(a.type)
-
- for m in members:
- if m.isAttr() and not m.readonly:
- addUnionTypes(m.type)
-
- return CGWrapper(CGList(SortedDictValues(unionConversions), "\n"),
- post="\n\n")
-
-class Argument():
- """
- A class for outputting the type and name of an argument
- """
- def __init__(self, argType, name):
- self.argType = argType
- self.name = name
- def __str__(self):
- return self.argType + ' ' + self.name
-
-class CGAbstractMethod(CGThing):
- """
- An abstract class for generating code for a method. Subclasses
- should override definition_body to create the actual code.
-
- descriptor is the descriptor for the interface the method is associated with
-
- name is the name of the method as a string
-
- returnType is the IDLType of the return value
-
- args is a list of Argument objects
-
- inline should be True to generate an inline method, whose body is
- part of the declaration.
-
- alwaysInline should be True to generate an inline method annotated with
- MOZ_ALWAYS_INLINE.
-
- static should be True to generate a static method, which only has
- a definition.
-
- If templateArgs is not None it should be a list of strings containing
- template arguments, and the function will be templatized using those
- arguments.
- """
- def __init__(self, descriptor, name, returnType, args, inline=False, alwaysInline=False, static=False, templateArgs=None):
- CGThing.__init__(self)
- self.descriptor = descriptor
- self.name = name
- self.returnType = returnType
- self.args = args
- self.inline = inline
- self.alwaysInline = alwaysInline
- self.static = static
- self.templateArgs = templateArgs
- def _argstring(self):
- return ', '.join([str(a) for a in self.args])
- def _template(self):
- if self.templateArgs is None:
- return ''
- return 'template <%s>\n' % ', '.join(self.templateArgs)
- def _decorators(self):
- decorators = []
- if self.alwaysInline:
- decorators.append('MOZ_ALWAYS_INLINE')
- elif self.inline:
- decorators.append('inline')
- if self.static:
- decorators.append('static')
- decorators.append(self.returnType)
- maybeNewline = " " if self.inline else "\n"
- return ' '.join(decorators) + maybeNewline
- def declare(self):
- if self.inline:
- return self._define()
- return "%s%s%s(%s);\n" % (self._template(), self._decorators(), self.name, self._argstring())
- def _define(self):
- return self.definition_prologue() + "\n" + self.definition_body() + self.definition_epilogue()
- def define(self):
- return "" if self.inline else self._define()
- def definition_prologue(self):
- return "%s%s%s(%s)\n{" % (self._template(), self._decorators(),
- self.name, self._argstring())
- def definition_epilogue(self):
- return "\n}\n"
- def definition_body(self):
- assert(False) # Override me!
-
-class CGAbstractStaticMethod(CGAbstractMethod):
- """
- Abstract base class for codegen of implementation-only (no
- declaration) static methods.
- """
- def __init__(self, descriptor, name, returnType, args):
- CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
- inline=False, static=True)
- def declare(self):
- # We only have implementation
- return ""
-
-class CGAbstractClassHook(CGAbstractStaticMethod):
- """
- Meant for implementing JSClass hooks, like Finalize or Trace. Does very raw
- 'this' unwrapping as it assumes that the unwrapped type is always known.
- """
- def __init__(self, descriptor, name, returnType, args):
- CGAbstractStaticMethod.__init__(self, descriptor, name, returnType,
- args)
-
- def definition_body_prologue(self):
- return """
- %s* self = UnwrapDOMObject<%s>(obj, eRegularDOMObject);
-""" % (self.descriptor.nativeType, self.descriptor.nativeType)
-
- def definition_body(self):
- return self.definition_body_prologue() + self.generate_code()
-
- def generate_code(self):
- # Override me
- assert(False)
-
-class CGAddPropertyHook(CGAbstractClassHook):
- """
- A hook for addProperty, used to preserve our wrapper from GC.
- """
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
- Argument('JSHandleId', 'id'), Argument('JSMutableHandleValue', 'vp')]
- CGAbstractClassHook.__init__(self, descriptor, ADDPROPERTY_HOOK_NAME,
- 'JSBool', args)
-
- def generate_code(self):
- # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=774279
- # Using a real trace hook might enable us to deal with non-nsISupports
- # wrappercached things here.
- assert self.descriptor.nativeIsISupports
- return """ nsContentUtils::PreserveWrapper(reinterpret_cast<nsISupports*>(self), self);
- return true;"""
-
-def finalizeHook(descriptor, hookName, context):
- if descriptor.customFinalize:
- return """if (self) {
- self->%s(%s);
-}""" % (hookName, context)
- clearWrapper = "ClearWrapper(self, self);\n" if descriptor.wrapperCache else ""
- if descriptor.workers:
- release = "self->Release();"
- else:
- assert descriptor.nativeIsISupports
- release = """XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
-if (rt) {
- rt->DeferredRelease(reinterpret_cast<nsISupports*>(self));
-} else {
- NS_RELEASE(self);
-}"""
- return clearWrapper + release
-
-class CGClassFinalizeHook(CGAbstractClassHook):
- """
- A hook for finalize, used to release our native object.
- """
- def __init__(self, descriptor):
- args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'obj')]
- CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME,
- 'void', args)
-
- def generate_code(self):
- return CGIndenter(CGGeneric(finalizeHook(self.descriptor, self.name, self.args[0].name))).define()
-
-class CGClassTraceHook(CGAbstractClassHook):
- """
- A hook to trace through our native object; used for GC and CC
- """
- def __init__(self, descriptor):
- args = [Argument('JSTracer*', 'trc'), Argument('JSObject*', 'obj')]
- CGAbstractClassHook.__init__(self, descriptor, TRACE_HOOK_NAME, 'void',
- args)
-
- def generate_code(self):
- return """ if (self) {
- self->%s(%s);
- }""" % (self.name, self.args[0].name)
-
-class CGClassConstructHook(CGAbstractStaticMethod):
- """
- JS-visible constructor for our objects
- """
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'), Argument('JS::Value*', 'vp')]
- CGAbstractStaticMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME,
- 'JSBool', args)
- self._ctor = self.descriptor.interface.ctor()
-
- def define(self):
- if not self._ctor:
- return ""
- return CGAbstractStaticMethod.define(self)
-
- def definition_body(self):
- return self.generate_code()
-
- def generate_code(self):
- preamble = """
- JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
-"""
- if self.descriptor.workers:
- preArgs = ["cx", "obj"]
- else:
- preamble += """
- nsISupports* global;
- xpc_qsSelfRef globalRef;
- {
- nsresult rv;
- JS::Value val = OBJECT_TO_JSVAL(obj);
- rv = xpc_qsUnwrapArg<nsISupports>(cx, val, &global, &globalRef.ptr, &val);
- if (NS_FAILED(rv)) {
- return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
- }
- }
-"""
- preArgs = ["global"]
-
- name = self._ctor.identifier.name
- nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
- callGenerator = CGMethodCall(preArgs, nativeName, True,
- self.descriptor, self._ctor)
- return preamble + callGenerator.define();
-
-class CGClassHasInstanceHook(CGAbstractStaticMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
- Argument('JSMutableHandleValue', 'vp'), Argument('JSBool*', 'bp')]
- CGAbstractStaticMethod.__init__(self, descriptor, HASINSTANCE_HOOK_NAME,
- 'JSBool', args)
-
- def define(self):
- if not self.descriptor.hasInstanceInterface:
- return ""
- return CGAbstractStaticMethod.define(self)
-
- def definition_body(self):
- return self.generate_code()
-
- def generate_code(self):
- return """ if (!vp.isObject()) {
- *bp = false;
- return true;
- }
-
- jsval protov;
- if (!JS_GetProperty(cx, obj, "prototype", &protov))
- return false;
- if (!protov.isObject()) {
- JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE,
- "%s");
- return false;
- }
- JSObject *objProto = &protov.toObject();
-
- JSObject* instance = &vp.toObject();
- JSObject* proto;
- if (!JS_GetPrototype(cx, instance, &proto))
- return false;
- while (proto) {
- if (proto == objProto) {
- *bp = true;
- return true;
- }
- if (!JS_GetPrototype(cx, proto, &proto))
- return false;
- }
-
- nsISupports* native =
- nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, instance);
- nsCOMPtr<%s> qiResult = do_QueryInterface(native);
- *bp = !!qiResult;
- return true;
-""" % (self.descriptor.name, self.descriptor.hasInstanceInterface)
-
-def isChromeOnly(m):
- return m.getExtendedAttribute("ChromeOnly")
-
-class PropertyDefiner:
- """
- A common superclass for defining things on prototype objects.
-
- Subclasses should implement generateArray to generate the actual arrays of
- things we're defining. They should also set self.chrome to the list of
- things exposed to chrome and self.regular to the list of things exposed to
- web pages. self.chrome must be a superset of self.regular but also include
- all the ChromeOnly stuff.
- """
- def __init__(self, descriptor, name):
- self.descriptor = descriptor
- self.name = name
- # self.prefCacheData will store an array of (prefname, bool*)
- # pairs for our bool var caches. generateArray will fill it
- # in as needed.
- self.prefCacheData = []
- def hasChromeOnly(self):
- return len(self.chrome) > len(self.regular)
- def hasNonChromeOnly(self):
- return len(self.regular) > 0
- def variableName(self, chrome):
- if chrome and self.hasChromeOnly():
- return "sChrome" + self.name
- if self.hasNonChromeOnly():
- return "s" + self.name
- return "NULL"
- def usedForXrays(self, chrome):
- # We only need Xrays for methods, attributes and constants. And we only
- # need them for the non-chrome ones if we have no chromeonly things.
- # Otherwise (we have chromeonly attributes) we need Xrays for the chrome
- # methods/attributes/constants. Finally, in workers there are no Xrays.
- return ((self.name is "Methods" or self.name is "Attributes" or
- self.name is "Constants") and
- chrome == self.hasChromeOnly() and
- not self.descriptor.workers)
-
- def __str__(self):
- # We only need to generate id arrays for things that will end
- # up used via ResolveProperty or EnumerateProperties.
- str = self.generateArray(self.regular, self.variableName(False),
- self.usedForXrays(False))
- if self.hasChromeOnly():
- str += self.generateArray(self.chrome, self.variableName(True),
- self.usedForXrays(True))
- return str
-
- @staticmethod
- def getControllingPref(interfaceMember):
- prefName = interfaceMember.getExtendedAttribute("Pref")
- if prefName is None:
- return None
- # It's a list of strings
- assert(len(prefName) is 1)
- assert(prefName[0] is not None)
- return prefName[0]
-
- def generatePrefableArray(self, array, name, specTemplate, specTerminator,
- specType, getPref, getDataTuple, doIdArrays):
- """
- This method generates our various arrays.
-
- array is an array of interface members as passed to generateArray
-
- name is the name as passed to generateArray
-
- specTemplate is a template for each entry of the spec array
-
- specTerminator is a terminator for the spec array (inserted every time
- our controlling pref changes and at the end of the array)
-
- specType is the actual typename of our spec
-
- getPref is a callback function that takes an array entry and returns
- the corresponding pref value.
-
- getDataTuple is a callback function that takes an array entry and
- returns a tuple suitable for substitution into specTemplate.
- """
-
- # We want to generate a single list of specs, but with specTerminator
- # inserted at every point where the pref name controlling the member
- # changes. That will make sure the order of the properties as exposed
- # on the interface and interface prototype objects does not change when
- # pref control is added to members while still allowing us to define all
- # the members in the smallest number of JSAPI calls.
- assert(len(array) is not 0)
- lastPref = getPref(array[0]) # So we won't put a specTerminator
- # at the very front of the list.
- specs = []
- prefableSpecs = []
- if doIdArrays:
- prefableIds = []
-
- prefableTemplate = ' { true, &%s[%d] }'
- prefCacheTemplate = '&%s[%d].enabled'
- def switchToPref(props, pref):
- # Remember the info about where our pref-controlled
- # booleans live.
- if pref is not None:
- props.prefCacheData.append(
- (pref, prefCacheTemplate % (name, len(prefableSpecs)))
- )
- # Set up pointers to the new sets of specs and ids
- # inside prefableSpecs and prefableIds
- prefableSpecs.append(prefableTemplate %
- (name + "_specs", len(specs)))
-
- switchToPref(self, lastPref)
-
- for member in array:
- curPref = getPref(member)
- if lastPref != curPref:
- # Terminate previous list
- specs.append(specTerminator)
- # And switch to our new pref
- switchToPref(self, curPref)
- lastPref = curPref
- # And the actual spec
- specs.append(specTemplate % getDataTuple(member))
- specs.append(specTerminator)
- prefableSpecs.append(" { false, NULL }");
-
- arrays = (("static %s %s_specs[] = {\n" +
- ',\n'.join(specs) + "\n" +
- "};\n\n" +
- "static Prefable<%s> %s[] = {\n" +
- ',\n'.join(prefableSpecs) + "\n" +
- "};\n\n") % (specType, name, specType, name))
- if doIdArrays:
- arrays += ("static jsid %s_ids[%i] = { JSID_VOID };\n\n" %
- (name, len(specs)))
- return arrays
-
-
-# The length of a method is the maximum of the lengths of the
-# argument lists of all its overloads.
-def methodLength(method):
- signatures = method.signatures()
- return max([len(arguments) for (retType, arguments) in signatures])
-
-class MethodDefiner(PropertyDefiner):
- """
- A class for defining methods on a prototype object.
- """
- def __init__(self, descriptor, name, static):
- PropertyDefiner.__init__(self, descriptor, name)
-
- # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822
- # We should be able to check for special operations without an
- # identifier. For now we check if the name starts with __
- methods = [m for m in descriptor.interface.members if
- m.isMethod() and m.isStatic() == static and
- not m.isIdentifierLess()]
- self.chrome = [{"name": m.identifier.name,
- "length": methodLength(m),
- "flags": "JSPROP_ENUMERATE",
- "pref": PropertyDefiner.getControllingPref(m) }
- for m in methods]
- self.regular = [{"name": m.identifier.name,
- "length": methodLength(m),
- "flags": "JSPROP_ENUMERATE",
- "pref": PropertyDefiner.getControllingPref(m) }
- for m in methods if not isChromeOnly(m)]
-
- # FIXME Check for an existing iterator on the interface first.
- if any(m.isGetter() and m.isIndexed() for m in methods):
- self.chrome.append({"name": 'iterator',
- "methodInfo": False,
- "nativeName": "JS_ArrayIterator",
- "length": 0,
- "flags": "JSPROP_ENUMERATE",
- "pref": None })
- self.regular.append({"name": 'iterator',
- "methodInfo": False,
- "nativeName": "JS_ArrayIterator",
- "length": 0,
- "flags": "JSPROP_ENUMERATE",
- "pref": None })
-
- if not descriptor.interface.parent and not static and not descriptor.workers:
- self.chrome.append({"name": 'QueryInterface',
- "methodInfo": False,
- "length": 1,
- "flags": "0",
- "pref": None })
-
- if static:
- if not descriptor.interface.hasInterfaceObject():
- # static methods go on the interface object
- assert not self.hasChromeOnly() and not self.hasNonChromeOnly()
- else:
- if not descriptor.interface.hasInterfacePrototypeObject():
- # non-static methods go on the interface prototype object
- assert not self.hasChromeOnly() and not self.hasNonChromeOnly()
-
- def generateArray(self, array, name, doIdArrays):
- if len(array) == 0:
- return ""
-
- def pref(m):
- return m["pref"]
-
- def specData(m):
- if m.get("methodInfo", True):
- jitinfo = ("&%s_methodinfo" % m["name"])
- accessor = "genericMethod"
- else:
- jitinfo = "nullptr"
- accessor = m.get("nativeName", m["name"])
- return (m["name"], accessor, jitinfo, m["length"], m["flags"])
-
- return self.generatePrefableArray(
- array, name,
- ' JS_FNINFO("%s", %s, %s, %s, %s)',
- ' JS_FS_END',
- 'JSFunctionSpec',
- pref, specData, doIdArrays)
-
-class AttrDefiner(PropertyDefiner):
- def __init__(self, descriptor, name):
- PropertyDefiner.__init__(self, descriptor, name)
- self.name = name
- self.chrome = [m for m in descriptor.interface.members if m.isAttr()]
- self.regular = [m for m in self.chrome if not isChromeOnly(m)]
-
- def generateArray(self, array, name, doIdArrays):
- if len(array) == 0:
- return ""
-
- def flags(attr):
- return "JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS"
-
- def getter(attr):
- native = ("genericLenientGetter" if attr.hasLenientThis()
- else "genericGetter")
- return ("{(JSPropertyOp)%(native)s, &%(name)s_getterinfo}"
- % {"name" : attr.identifier.name,
- "native" : native})
-
- def setter(attr):
- if attr.readonly:
- return "JSOP_NULLWRAPPER"
- native = ("genericLenientSetter" if attr.hasLenientThis()
- else "genericSetter")
- return ("{(JSStrictPropertyOp)%(native)s, &%(name)s_setterinfo}"
- % {"name" : attr.identifier.name,
- "native" : native})
-
- def specData(attr):
- return (attr.identifier.name, flags(attr), getter(attr),
- setter(attr))
-
- return self.generatePrefableArray(
- array, name,
- ' { "%s", 0, %s, %s, %s}',
- ' { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }',
- 'JSPropertySpec',
- PropertyDefiner.getControllingPref, specData, doIdArrays)
-
-class ConstDefiner(PropertyDefiner):
- """
- A class for definining constants on the interface object
- """
- def __init__(self, descriptor, name):
- PropertyDefiner.__init__(self, descriptor, name)
- self.name = name
- self.chrome = [m for m in descriptor.interface.members if m.isConst()]
- self.regular = [m for m in self.chrome if not isChromeOnly(m)]
-
- def generateArray(self, array, name, doIdArrays):
- if len(array) == 0:
- return ""
-
- def specData(const):
- return (const.identifier.name,
- convertConstIDLValueToJSVal(const.value))
-
- return self.generatePrefableArray(
- array, name,
- ' { "%s", %s }',
- ' { 0, JSVAL_VOID }',
- 'ConstantSpec',
- PropertyDefiner.getControllingPref, specData, doIdArrays)
-
-class PropertyArrays():
- def __init__(self, descriptor):
- self.staticMethods = MethodDefiner(descriptor, "StaticMethods", True)
- self.methods = MethodDefiner(descriptor, "Methods", False)
- self.attrs = AttrDefiner(descriptor, "Attributes")
- self.consts = ConstDefiner(descriptor, "Constants")
-
- @staticmethod
- def arrayNames():
- return [ "staticMethods", "methods", "attrs", "consts" ]
-
- @staticmethod
- def xrayRelevantArrayNames():
- return [ "methods", "attrs", "consts" ]
-
- def hasChromeOnly(self):
- return reduce(lambda b, a: b or getattr(self, a).hasChromeOnly(),
- self.arrayNames(), False)
- def variableNames(self, chrome):
- names = {}
- for array in self.arrayNames():
- names[array] = getattr(self, array).variableName(chrome)
- return names
- def __str__(self):
- define = ""
- for array in self.arrayNames():
- define += str(getattr(self, array))
- return define
-
-class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
- """
- Generate the CreateInterfaceObjects method for an interface descriptor.
-
- properties should be a PropertyArrays instance.
- """
- def __init__(self, descriptor, properties):
- args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal'),
- Argument('JSObject*', 'aReceiver')]
- CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'JSObject*', args)
- self.properties = properties
- def definition_body(self):
- protoChain = self.descriptor.prototypeChain
- if len(protoChain) == 1:
- getParentProto = "JS_GetObjectPrototype(aCx, aGlobal)"
- else:
- parentProtoName = self.descriptor.prototypeChain[-2]
- getParentProto = ("%s::GetProtoObject(aCx, aGlobal, aReceiver)" %
- toBindingNamespace(parentProtoName))
-
- needInterfaceObject = self.descriptor.interface.hasInterfaceObject()
- needInterfacePrototypeObject = self.descriptor.interface.hasInterfacePrototypeObject()
-
- # if we don't need to create anything, why are we generating this?
- assert needInterfaceObject or needInterfacePrototypeObject
-
- idsToInit = []
- # There is no need to init any IDs in workers, because worker bindings
- # don't have Xrays.
- if not self.descriptor.workers:
- for var in self.properties.xrayRelevantArrayNames():
- props = getattr(self.properties, var)
- # We only have non-chrome ids to init if we have no chrome ids.
- if props.hasChromeOnly():
- idsToInit.append(props.variableName(True))
- elif props.hasNonChromeOnly():
- idsToInit.append(props.variableName(False))
- if len(idsToInit) > 0:
- initIds = CGList(
- [CGGeneric("!InitIds(aCx, %s, %s_ids)" % (varname, varname)) for
- varname in idsToInit], ' ||\n')
- if len(idsToInit) > 1:
- initIds = CGWrapper(initIds, pre="(", post=")", reindent=True)
- initIds = CGList(
- [CGGeneric("%s_ids[0] == JSID_VOID &&" % idsToInit[0]), initIds],
- "\n")
- initIds = CGWrapper(initIds, pre="if (", post=") {", reindent=True)
- initIds = CGList(
- [initIds,
- CGGeneric((" %s_ids[0] = JSID_VOID;\n"
- " return NULL;") % idsToInit[0]),
- CGGeneric("}")],
- "\n")
- else:
- initIds = None
-
- prefCacheData = []
- for var in self.properties.arrayNames():
- props = getattr(self.properties, var)
- prefCacheData.extend(props.prefCacheData)
- if len(prefCacheData) is not 0:
- prefCacheData = [
- CGGeneric('Preferences::AddBoolVarCache(%s, "%s");' % (ptr, pref)) for
- (pref, ptr) in prefCacheData]
- prefCache = CGWrapper(CGIndenter(CGList(prefCacheData, "\n")),
- pre=("static bool sPrefCachesInited = false;\n"
- "if (!sPrefCachesInited) {\n"
- " sPrefCachesInited = true;\n"),
- post="\n}")
- else:
- prefCache = None
-
- getParentProto = ("JSObject* parentProto = %s;\n" +
- "if (!parentProto) {\n" +
- " return NULL;\n" +
- "}\n") % getParentProto
-
- needInterfaceObjectClass = (needInterfaceObject and
- self.descriptor.hasInstanceInterface)
- needConstructor = (needInterfaceObject and
- not self.descriptor.hasInstanceInterface)
- if self.descriptor.interface.ctor():
- constructHook = CONSTRUCT_HOOK_NAME
- constructArgs = methodLength(self.descriptor.interface.ctor())
- else:
- constructHook = "ThrowingConstructor"
- constructArgs = 0
-
- if self.descriptor.concrete:
- if self.descriptor.proxy:
- domClass = "&Class"
- else:
- domClass = "&Class.mClass"
- else:
- domClass = "nullptr"
-
- call = """return dom::CreateInterfaceObjects(aCx, aGlobal, aReceiver, parentProto,
- %s, %s, %s, %d,
- %s,
- %%(methods)s, %%(attrs)s,
- %%(consts)s, %%(staticMethods)s,
- %s);""" % (
- "&PrototypeClass" if needInterfacePrototypeObject else "NULL",
- "&InterfaceObjectClass" if needInterfaceObjectClass else "NULL",
- constructHook if needConstructor else "NULL",
- constructArgs,
- domClass,
- '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "NULL")
- if self.properties.hasChromeOnly():
- if self.descriptor.workers:
- accessCheck = "mozilla::dom::workers::GetWorkerPrivateFromContext(aCx)->IsChromeWorker()"
- else:
- accessCheck = "xpc::AccessCheck::isChrome(js::GetObjectCompartment(aGlobal))"
- chrome = CGIfWrapper(CGGeneric(call % self.properties.variableNames(True)),
- accessCheck)
- chrome = CGWrapper(chrome, pre="\n\n")
- else:
- chrome = None
-
- functionBody = CGList(
- [CGGeneric(getParentProto), initIds, prefCache, chrome,
- CGGeneric(call % self.properties.variableNames(False))],
- "\n\n")
- return CGIndenter(functionBody).define()
-
-class CGGetPerInterfaceObject(CGAbstractMethod):
- """
- A method for getting a per-interface object (a prototype object or interface
- constructor object).
- """
- def __init__(self, descriptor, name, idPrefix=""):
- args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal'),
- Argument('JSObject*', 'aReceiver')]
- CGAbstractMethod.__init__(self, descriptor, name,
- 'JSObject*', args, inline=True)
- self.id = idPrefix + "id::" + self.descriptor.name
- def definition_body(self):
- return """
-
- /* aGlobal and aReceiver are usually the same, but they can be different
- too. For example a sandbox often has an xray wrapper for a window as the
- prototype of the sandbox's global. In that case aReceiver is the xray
- wrapper and aGlobal is the sandbox's global.
- */
-
- /* Make sure our global is sane. Hopefully we can remove this sometime */
- if (!(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL)) {
- return NULL;
- }
- /* Check to see whether the interface objects are already installed */
- JSObject** protoOrIfaceArray = GetProtoOrIfaceArray(aGlobal);
- JSObject* cachedObject = protoOrIfaceArray[%s];
- if (!cachedObject) {
- protoOrIfaceArray[%s] = cachedObject = CreateInterfaceObjects(aCx, aGlobal, aReceiver);
- }
-
- /* cachedObject might _still_ be null, but that's OK */
- return cachedObject;""" % (self.id, self.id)
-
-class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
- """
- A method for getting the interface prototype object.
- """
- def __init__(self, descriptor):
- CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
- "prototypes::")
- def definition_body(self):
- return """
- /* Get the interface prototype object for this class. This will create the
- object as needed. */""" + CGGetPerInterfaceObject.definition_body(self)
-
-class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
- """
- A method for getting the interface constructor object.
- """
- def __init__(self, descriptor):
- CGGetPerInterfaceObject.__init__(self, descriptor, "GetConstructorObject",
- "constructors::")
- def definition_body(self):
- return """
- /* Get the interface object for this class. This will create the object as
- needed. */""" + CGGetPerInterfaceObject.definition_body(self)
-
-def CheckPref(descriptor, globalName, varName, retval, wrapperCache = None):
- """
- Check whether bindings should be enabled for this descriptor. If not, set
- varName to false and return retval.
- """
- if not descriptor.prefable:
- return ""
-
- if wrapperCache:
- wrapperCache = " %s->ClearIsDOMBinding();\n" % (wrapperCache)
- else:
- wrapperCache = ""
-
- failureCode = (" %s = false;\n" +
- " return %s;") % (varName, retval)
- return """
- {
- XPCWrappedNativeScope* scope =
- XPCWrappedNativeScope::FindInJSObjectScope(aCx, %s);
- if (!scope) {
-%s
- }
-
- if (!scope->ExperimentalBindingsEnabled()) {
-%s%s
- }
- }
-""" % (globalName, failureCode, wrapperCache, failureCode)
-
-class CGDefineDOMInterfaceMethod(CGAbstractMethod):
- """
- A method for resolve hooks to try to lazily define the interface object for
- a given interface.
- """
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aReceiver'),
- Argument('bool*', 'aEnabled')]
- CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'bool', args)
-
- def declare(self):
- if self.descriptor.workers:
- return ''
- return CGAbstractMethod.declare(self)
-
- def define(self):
- if self.descriptor.workers:
- return ''
- return CGAbstractMethod.define(self)
-
- def definition_body(self):
- if self.descriptor.interface.hasInterfacePrototypeObject():
- # We depend on GetProtoObject defining an interface constructor
- # object as needed.
- getter = "GetProtoObject"
- else:
- getter = "GetConstructorObject"
-
- return (" JSObject* global = JS_GetGlobalForObject(aCx, aReceiver);\n" +
- CheckPref(self.descriptor, "global", "*aEnabled", "false") +
- """
- *aEnabled = true;
- return !!%s(aCx, global, aReceiver);""" % (getter))
-
-class CGPrefEnabled(CGAbstractMethod):
- """
- A method for testing whether the preference controlling this
- interface is enabled. When it's not, the interface should not be
- visible on the global.
- """
- def __init__(self, descriptor):
- CGAbstractMethod.__init__(self, descriptor, 'PrefEnabled', 'bool', [])
-
- def declare(self):
- return CGAbstractMethod.declare(self)
-
- def define(self):
- return CGAbstractMethod.define(self)
-
- def definition_body(self):
- return " return %s::PrefEnabled();" % self.descriptor.nativeType
-
-class CGIsMethod(CGAbstractMethod):
- def __init__(self, descriptor):
- args = [Argument('JSObject*', 'obj')]
- CGAbstractMethod.__init__(self, descriptor, 'Is', 'bool', args)
-
- def definition_body(self):
- # Non-proxy implementation would check
- # js::GetObjectJSClass(obj) == &Class.mBase
- return """ return IsProxy(obj);"""
-
-def CreateBindingJSObject(descriptor, parent):
- if descriptor.proxy:
- create = """ JSObject *obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
- JS::PrivateValue(aObject), proto, %s);
- if (!obj) {
- return NULL;
- }
-
-"""
- else:
- create = """ JSObject* obj = JS_NewObject(aCx, &Class.mBase, proto, %s);
- if (!obj) {
- return NULL;
- }
-
- js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
-"""
- return create % parent
-
-class CGWrapWithCacheMethod(CGAbstractMethod):
- def __init__(self, descriptor):
- assert descriptor.interface.hasInterfacePrototypeObject()
- args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
- Argument(descriptor.nativeType + '*', 'aObject'),
- Argument('nsWrapperCache*', 'aCache'),
- Argument('bool*', 'aTriedToWrap')]
- CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
-
- def definition_body(self):
- if self.descriptor.workers:
- return """ *aTriedToWrap = true;
- return aObject->GetJSObject();"""
-
- return """ *aTriedToWrap = true;
-
- JSObject* parent = WrapNativeParent(aCx, aScope, aObject->GetParentObject());
- if (!parent) {
- return NULL;
- }
-
- JSAutoCompartment ac(aCx, parent);
- JSObject* global = JS_GetGlobalForObject(aCx, parent);
-%s
- JSObject* proto = GetProtoObject(aCx, global, global);
- if (!proto) {
- return NULL;
- }
-
-%s
- NS_ADDREF(aObject);
-
- aCache->SetWrapper(obj);
-
- return obj;""" % (CheckPref(self.descriptor, "global", "*aTriedToWrap", "NULL", "aCache"),
- CreateBindingJSObject(self.descriptor, "parent"))
-
-class CGWrapMethod(CGAbstractMethod):
- def __init__(self, descriptor):
- # XXX can we wrap if we don't have an interface prototype object?
- assert descriptor.interface.hasInterfacePrototypeObject()
- args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
- Argument('T*', 'aObject'), Argument('bool*', 'aTriedToWrap')]
- CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args, inline=True, templateArgs=["class T"])
-
- def definition_body(self):
- return " return Wrap(aCx, aScope, aObject, aObject, aTriedToWrap);"
-
-class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
- def __init__(self, descriptor):
- # XXX can we wrap if we don't have an interface prototype object?
- assert descriptor.interface.hasInterfacePrototypeObject()
- args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
- Argument(descriptor.nativeType + '*', 'aObject')]
- CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
-
- def definition_body(self):
- return """
- JSObject* global = JS_GetGlobalForObject(aCx, aScope);
- JSObject* proto = GetProtoObject(aCx, global, global);
- if (!proto) {
- return NULL;
- }
-
-%s
- NS_ADDREF(aObject);
-
- return obj;""" % CreateBindingJSObject(self.descriptor, "global")
-
-builtinNames = {
- IDLType.Tags.bool: 'bool',
- IDLType.Tags.int8: 'int8_t',
- IDLType.Tags.int16: 'int16_t',
- IDLType.Tags.int32: 'int32_t',
- IDLType.Tags.int64: 'int64_t',
- IDLType.Tags.uint8: 'uint8_t',
- IDLType.Tags.uint16: 'uint16_t',
- IDLType.Tags.uint32: 'uint32_t',
- IDLType.Tags.uint64: 'uint64_t',
- IDLType.Tags.float: 'float',
- IDLType.Tags.double: 'double'
-}
-
-numericTags = [
- IDLType.Tags.int8, IDLType.Tags.uint8,
- IDLType.Tags.int16, IDLType.Tags.uint16,
- IDLType.Tags.int32, IDLType.Tags.uint32,
- IDLType.Tags.int64, IDLType.Tags.uint64,
- IDLType.Tags.float, IDLType.Tags.double
- ]
-
-class CastableObjectUnwrapper():
- """
- A class for unwrapping an object named by the "source" argument
- based on the passed-in descriptor and storing it in a variable
- called by the name in the "target" argument.
-
- codeOnFailure is the code to run if unwrapping fails.
- """
- def __init__(self, descriptor, source, target, codeOnFailure):
- assert descriptor.castable
-
- self.substitution = { "type" : descriptor.nativeType,
- "protoID" : "prototypes::id::" + descriptor.name,
- "source" : source,
- "target" : target,
- "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure), 4).define() }
- if descriptor.hasXPConnectImpls:
- # We don't use xpc_qsUnwrapThis because it will always throw on
- # unwrap failure, whereas we want to control whether we throw or
- # not.
- self.substitution["codeOnFailure"] = CGIndenter(CGGeneric(string.Template(
- "${type} *objPtr;\n"
- "xpc_qsSelfRef objRef;\n"
- "JS::Value val = JS::ObjectValue(*${source});\n"
- "nsresult rv = xpc_qsUnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
- "if (NS_FAILED(rv)) {\n"
- "${codeOnFailure}\n"
- "}\n"
- "// We should be castable!\n"
- "MOZ_ASSERT(!objRef.ptr);\n"
- "// We should have an object, too!\n"
- "MOZ_ASSERT(objPtr);\n"
- "${target} = objPtr;").substitute(self.substitution)), 4).define()
-
- def __str__(self):
- return string.Template(
-"""{
- nsresult rv = UnwrapObject<${protoID}, ${type}>(cx, ${source}, ${target});
- if (NS_FAILED(rv)) {
-${codeOnFailure}
- }
-}""").substitute(self.substitution)
-
-class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
- """
- As CastableObjectUnwrapper, but defaulting to throwing if unwrapping fails
- """
- def __init__(self, descriptor, source, target):
- CastableObjectUnwrapper.__init__(self, descriptor, source, target,
- "return Throw<%s>(cx, rv);" %
- toStringBool(not descriptor.workers))
-
-class CallbackObjectUnwrapper:
- """
- A class for unwrapping objects implemented in JS.
-
- |source| is the JSObject we want to use in native code.
- |target| is an nsCOMPtr of the appropriate type in which we store the result.
- """
- def __init__(self, descriptor, source, target, codeOnFailure=None):
- if codeOnFailure is None:
- codeOnFailure = ("return Throw<%s>(cx, rv);" %
- toStringBool(not descriptor.workers))
- self.descriptor = descriptor
- self.substitution = { "nativeType" : descriptor.nativeType,
- "source" : source,
- "target" : target,
- "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure)).define() }
-
- def __str__(self):
- if self.descriptor.workers:
- return string.Template(
- "${target} = ${source};"
- ).substitute(self.substitution)
-
- return string.Template(
- """nsresult rv;
-XPCCallContext ccx(JS_CALLER, cx);
-if (!ccx.IsValid()) {
- rv = NS_ERROR_XPC_BAD_CONVERT_JS;
-${codeOnFailure}
-}
-
-const nsIID& iid = NS_GET_IID(${nativeType});
-nsRefPtr<nsXPCWrappedJS> wrappedJS;
-rv = nsXPCWrappedJS::GetNewOrUsed(ccx, ${source}, iid,
- NULL, getter_AddRefs(wrappedJS));
-if (NS_FAILED(rv) || !wrappedJS) {
-${codeOnFailure}
-}
-
-// Use a temp nsCOMPtr for the null-check, because ${target} might be
-// OwningNonNull, not an nsCOMPtr.
-nsCOMPtr<${nativeType}> tmp = do_QueryObject(wrappedJS.get());
-if (!tmp) {
-${codeOnFailure}
-}
-${target} = tmp.forget();""").substitute(self.substitution)
-
-def dictionaryHasSequenceMember(dictionary):
- return (any(typeIsSequenceOrHasSequenceMember(m.type) for m in
- dictionary.members) or
- (dictionary.parent and
- dictionaryHasSequenceMember(dictionary.parent)))
-
-def typeIsSequenceOrHasSequenceMember(type):
- if type.nullable():
- type = type.inner
- if type.isSequence():
- return True
- if type.isArray():
- elementType = type.inner
- return typeIsSequenceOrHasSequenceMember(elementType)
- if type.isDictionary():
- return dictionaryHasSequenceMember(type.inner)
- if type.isUnion():
- return any(typeIsSequenceOrHasSequenceMember(m.type) for m in
- type.flatMemberTypes)
- return False
-
-def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
- isDefinitelyObject=False,
- isMember=False,
- isOptional=False,
- invalidEnumValueFatal=True,
- defaultValue=None,
- treatNullAs="Default",
- treatUndefinedAs="Default",
- isEnforceRange=False,
- isClamp=False):
- """
- Get a template for converting a JS value to a native object based on the
- given type and descriptor. If failureCode is given, then we're actually
- testing whether we can convert the argument to the desired type. That
- means that failures to convert due to the JS value being the wrong type of
- value need to use failureCode instead of throwing exceptions. Failures to
- convert that are due to JS exceptions (from toString or valueOf methods) or
- out of memory conditions need to throw exceptions no matter what
- failureCode is.
-
- If isDefinitelyObject is True, that means we know the value
- isObject() and we have no need to recheck that.
-
- if isMember is True, we're being converted from a property of some
- JS object, not from an actual method argument, so we can't rely on
- our jsval being rooted or outliving us in any way. Any caller
- passing true needs to ensure that it is handled correctly in
- typeIsSequenceOrHasSequenceMember.
-
- If isOptional is true, then we are doing conversion of an optional
- argument with no default value.
-
- invalidEnumValueFatal controls whether an invalid enum value conversion
- attempt will throw (if true) or simply return without doing anything (if
- false).
-
- If defaultValue is not None, it's the IDL default value for this conversion
-
- If isEnforceRange is true, we're converting an integer and throwing if the
- value is out of range.
-
- If isClamp is true, we're converting an integer and clamping if the
- value is out of range.
-
- The return value from this function is a tuple consisting of four things:
-
- 1) A string representing the conversion code. This will have template
- substitution performed on it as follows:
-
- ${val} replaced by an expression for the JS::Value in question
- ${valPtr} is a pointer to the JS::Value in question
- ${holderName} replaced by the holder's name, if any
- ${declName} replaced by the declaration's name
- ${haveValue} replaced by an expression that evaluates to a boolean
- for whether we have a JS::Value. Only used when
- defaultValue is not None.
-
- 2) A CGThing representing the native C++ type we're converting to
- (declType). This is allowed to be None if the conversion code is
- supposed to be used as-is.
- 3) A CGThing representing the type of a "holder" (holderType) which will
- hold a possible reference to the C++ thing whose type we returned in #1,
- or None if no such holder is needed.
- 4) A boolean indicating whether the caller has to do optional-argument handling.
- This will only be true if isOptional is true and if the returned template
- expects both declType and holderType to be wrapped in Optional<>, with
- ${declName} and ${holderName} adjusted to point to the Value() of the
- Optional, and Construct() calls to be made on the Optional<>s as needed.
-
- ${declName} must be in scope before the generated code is entered.
-
- If holderType is not None then ${holderName} must be in scope
- before the generated code is entered.
- """
- # If we have a defaultValue then we're not actually optional for
- # purposes of what we need to be declared as.
- assert(defaultValue is None or not isOptional)
-
- # Also, we should not have a defaultValue if we know we're an object
- assert(not isDefinitelyObject or defaultValue is None)
-
- # Helper functions for dealing with failures due to the JS value being the
- # wrong type of value
- def onFailureNotAnObject(failureCode):
- return CGWrapper(CGGeneric(
- failureCode or
- 'return ThrowErrorMessage(cx, MSG_NOT_OBJECT);'), post="\n")
- def onFailureBadType(failureCode, typeName):
- return CGWrapper(CGGeneric(
- failureCode or
- 'return ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "%s");' % typeName), post="\n")
-
- # A helper function for handling default values. Takes a template
- # body and the C++ code to set the default value and wraps the
- # given template body in handling for the default value.
- def handleDefault(template, setDefault):
- if defaultValue is None:
- return template
- return CGWrapper(
- CGIndenter(CGGeneric(template)),
- pre="if (${haveValue}) {\n",
- post=("\n"
- "} else {\n"
- "%s;\n"
- "}" %
- CGIndenter(CGGeneric(setDefault)).define())).define()
-
- # A helper function for handling null default values. Much like
- # handleDefault, but checks that the default value, if it exists, is null.
- def handleDefaultNull(template, codeToSetNull):
- if (defaultValue is not None and
- not isinstance(defaultValue, IDLNullValue)):
- raise TypeError("Can't handle non-null default value here")
- return handleDefault(template, codeToSetNull)
-
- # A helper function for wrapping up the template body for
- # possibly-nullable objecty stuff
- def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
- codeToSetNull, failureCode=None):
- if not isDefinitelyObject:
- # Handle the non-object cases by wrapping up the whole
- # thing in an if cascade.
- templateBody = (
- "if (${val}.isObject()) {\n" +
- CGIndenter(CGGeneric(templateBody)).define() + "\n")
- if type.nullable():
- templateBody += (
- "} else if (${val}.isNullOrUndefined()) {\n"
- " %s;\n" % codeToSetNull)
- templateBody += (
- "} else {\n" +
- CGIndenter(onFailureNotAnObject(failureCode)).define() +
- "}")
- if type.nullable():
- templateBody = handleDefaultNull(templateBody, codeToSetNull)
- else:
- assert(defaultValue is None)
-
- return templateBody
-
- assert not (isEnforceRange and isClamp) # These are mutually exclusive
-
- if type.isArray():
- raise TypeError("Can't handle array arguments yet")
-
- if type.isSequence():
- assert not isEnforceRange and not isClamp
-
- if failureCode is not None:
- raise TypeError("Can't handle sequences when failureCode is not None")
- nullable = type.nullable();
- # Be very careful not to change "type": we need it later
- if nullable:
- elementType = type.inner.inner
- else:
- elementType = type.inner
-
- # We have to be careful with reallocation behavior for arrays. In
- # particular, if we have a sequence of elements which are themselves
- # sequences (so nsAutoTArrays) or have sequences as members, we have a
- # problem. In that case, resizing the outermost nsAutoTarray to the
- # right size will memmove its elements, but nsAutoTArrays are not
- # memmovable and hence will end up with pointers to bogus memory, which
- # is bad. To deal with this, we disallow sequences, arrays,
- # dictionaries, and unions which contain sequences as sequence item
- # types. If WebIDL ever adds another container type, we'd have to
- # disallow it as well.
- if typeIsSequenceOrHasSequenceMember(elementType):
- raise TypeError("Can't handle a sequence containing another "
- "sequence as an element or member of an element. "
- "See the big comment explaining why.\n%s" %
- str(type.location))
-
- (elementTemplate, elementDeclType,
- elementHolderType, dealWithOptional) = getJSToNativeConversionTemplate(
- elementType, descriptorProvider, isMember=True)
- if dealWithOptional:
- raise TypeError("Shouldn't have optional things in sequences")
- if elementHolderType is not None:
- raise TypeError("Shouldn't need holders for sequences")
-
- typeName = CGWrapper(elementDeclType, pre="Sequence< ", post=" >")
- if nullable:
- typeName = CGWrapper(typeName, pre="Nullable< ", post=" >")
- arrayRef = "${declName}.Value()"
- else:
- arrayRef = "${declName}"
- # If we're optional, the const will come from the Optional
- mutableTypeName = typeName
- if not isOptional:
- typeName = CGWrapper(typeName, pre="const ")
-
- templateBody = ("""JSObject* seq = &${val}.toObject();\n
-if (!IsArrayLike(cx, seq)) {
- return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
-}
-uint32_t length;
-// JS_GetArrayLength actually works on all objects
-if (!JS_GetArrayLength(cx, seq, &length)) {
- return false;
-}
-Sequence< %s > &arr = const_cast< Sequence< %s >& >(%s);
-if (!arr.SetCapacity(length)) {
- return Throw<%s>(cx, NS_ERROR_OUT_OF_MEMORY);
-}
-for (uint32_t i = 0; i < length; ++i) {
- jsval temp;
- if (!JS_GetElement(cx, seq, i, &temp)) {
- return false;
- }
-""" % (toStringBool(descriptorProvider.workers),
- elementDeclType.define(),
- elementDeclType.define(),
- arrayRef,
- toStringBool(descriptorProvider.workers)))
-
- templateBody += CGIndenter(CGGeneric(
- string.Template(elementTemplate).substitute(
- {
- "val" : "temp",
- "valPtr": "&temp",
- "declName" : "(*arr.AppendElement())"
- }
- ))).define()
-
- templateBody += "\n}"
- templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
- type,
- "const_cast< %s & >(${declName}).SetNull()" % mutableTypeName.define())
- return (templateBody, typeName, None, isOptional)
-
- if type.isUnion():
- if isMember:
- raise TypeError("Can't handle unions as members, we have a "
- "holderType")
- nullable = type.nullable();
- if nullable:
- type = type.inner
-
- assert(defaultValue is None or
- (isinstance(defaultValue, IDLNullValue) and nullable))
-
- unionArgumentObj = "${holderName}"
- if isOptional or nullable:
- unionArgumentObj += ".ref()"
-
- memberTypes = type.flatMemberTypes
- names = []
-
- interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
- if len(interfaceMemberTypes) > 0:
- interfaceObject = []
- for memberType in interfaceMemberTypes:
- if type.isGeckoInterface():
- name = memberType.inner.identifier.name
- else:
- name = memberType.name
- interfaceObject.append(CGGeneric("(failed = !%s.TrySetTo%s(cx, ${val}, ${valPtr}, tryNext)) || !tryNext" % (unionArgumentObj, name)))
- names.append(name)
- interfaceObject = CGWrapper(CGList(interfaceObject, " ||\n"), pre="done = ", post=";\n", reindent=True)
- else:
- interfaceObject = None
-
- arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
- if len(arrayObjectMemberTypes) > 0:
- assert len(arrayObjectMemberTypes) == 1
- memberType = arrayObjectMemberTypes[0]
- name = memberType.name
- arrayObject = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
- # XXX Now we're supposed to check for an array or a platform object
- # that supports indexed properties... skip that last for now. It's a
- # bit of a pain.
- arrayObject = CGWrapper(CGIndenter(arrayObject),
- pre="if (IsArrayLike(cx, &argObj)) {\n",
- post="}")
- names.append(name)
- else:
- arrayObject = None
-
- dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
- if len(dateObjectMemberTypes) > 0:
- assert len(dateObjectMemberTypes) == 1
- memberType = dateObjectMemberTypes[0]
- name = memberType.name
- dateObject = CGGeneric("%s.SetTo%s(cx, ${val}, ${valPtr});\n"
- "done = true;" % (unionArgumentObj, name))
- dateObject = CGWrapper(CGIndenter(dateObject),
- pre="if (JS_ObjectIsDate(cx, &argObj)) {\n",
- post="\n}")
- names.append(name)
- else:
- dateObject = None
-
- callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
- if len(callbackMemberTypes) > 0:
- assert len(callbackMemberTypes) == 1
- memberType = callbackMemberTypes[0]
- name = memberType.name
- callbackObject = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
- names.append(name)
- else:
- callbackObject = None
-
- dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes)
- if len(dictionaryMemberTypes) > 0:
- raise TypeError("No support for unwrapping dictionaries as member "
- "of a union")
- else:
- dictionaryObject = None
-
- if callbackObject or dictionaryObject:
- nonPlatformObject = CGList([callbackObject, dictionaryObject], "\n")
- nonPlatformObject = CGWrapper(CGIndenter(nonPlatformObject),
- pre="if (!IsPlatformObject(cx, &argObj)) {\n",
- post="\n}")
- else:
- nonPlatformObject = None
-
- objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
- if len(objectMemberTypes) > 0:
- object = CGGeneric("%s.SetToObject(&argObj);\n"
- "done = true;" % unionArgumentObj)
- else:
- object = None
-
- hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object
- if hasObjectTypes:
- # If we try more specific object types first then we need to check
- # whether that succeeded before converting to object.
- if object and (interfaceObject or arrayObject or dateObject or nonPlatformObject):
- object = CGWrapper(CGIndenter(object), pre="if (!done) {\n",
- post=("\n}"))
-
- if arrayObject or dateObject or nonPlatformObject:
- # An object can be both an array object and not a platform
- # object, but we shouldn't have both in the union's members
- # because they are not distinguishable.
- assert not (arrayObject and nonPlatformObject)
- templateBody = CGList([arrayObject, dateObject, nonPlatformObject], " else ")
- else:
- templateBody = None
- if interfaceObject:
- if templateBody:
- templateBody = CGList([templateBody, object], "\n")
- templateBody = CGWrapper(CGIndenter(templateBody),
- pre="if (!done) {\n", post=("\n}"))
- templateBody = CGList([interfaceObject, templateBody], "\n")
- else:
- templateBody = CGList([templateBody, object], "\n")
-
- if any([arrayObject, dateObject, nonPlatformObject, object]):
- templateBody.prepend(CGGeneric("JSObject& argObj = ${val}.toObject();"))
- templateBody = CGWrapper(CGIndenter(templateBody),
- pre="if (${val}.isObject()) {\n",
- post="\n}")
- else:
- templateBody = CGGeneric()
-
- otherMemberTypes = filter(lambda t: t.isString() or t.isEnum(),
- memberTypes)
- otherMemberTypes.extend(t for t in memberTypes if t.isPrimitive())
- if len(otherMemberTypes) > 0:
- assert len(otherMemberTypes) == 1
- memberType = otherMemberTypes[0]
- if memberType.isEnum():
- name = memberType.inner.identifier.name
- else:
- name = memberType.name
- other = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
- names.append(name)
- if hasObjectTypes:
- other = CGWrapper(CGIndenter(other), "{\n", post="\n}")
- if object:
- join = " else "
- else:
- other = CGWrapper(other, pre="if (!done) ")
- join = "\n"
- templateBody = CGList([templateBody, other], join)
- else:
- other = None
-
- templateBody = CGWrapper(templateBody, pre="bool done = false, failed = false, tryNext;\n")
- throw = CGGeneric("if (failed) {\n"
- " return false;\n"
- "}\n"
- "if (!done) {\n"
- " return ThrowErrorMessage(cx, MSG_NOT_IN_UNION, \"%s\");\n"
- "}" % ", ".join(names))
- templateBody = CGWrapper(CGIndenter(CGList([templateBody, throw], "\n")), pre="{\n", post="\n}")
-
- typeName = type.name
- argumentTypeName = typeName + "Argument"
- if nullable:
- typeName = "Nullable<" + typeName + " >"
- if isOptional:
- nonConstDecl = "const_cast<Optional<" + typeName + " >& >(${declName})"
- else:
- nonConstDecl = "const_cast<" + typeName + "& >(${declName})"
- typeName = "const " + typeName
-
- def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
- null = CGGeneric("if (%s${val}.isNullOrUndefined()) {\n"
- " %s.SetNull();\n"
- "}" % (extraConditionForNull, setToNullVar))
- templateBody = CGWrapper(CGIndenter(templateBody), pre="{\n", post="\n}")
- return CGList([null, templateBody], " else ")
-
- if type.hasNullableType:
- templateBody = handleNull(templateBody, unionArgumentObj)
-
- declType = CGGeneric(typeName)
- holderType = CGGeneric(argumentTypeName)
- if isOptional:
- mutableDecl = nonConstDecl + ".Value()"
- declType = CGWrapper(declType, pre="const Optional<", post=" >")
- holderType = CGWrapper(holderType, pre="Maybe<", post=" >")
- constructDecl = CGGeneric(nonConstDecl + ".Construct();")
- if nullable:
- constructHolder = CGGeneric("${holderName}.construct(%s.SetValue());" % mutableDecl)
- else:
- constructHolder = CGGeneric("${holderName}.construct(${declName}.Value());")
- else:
- mutableDecl = nonConstDecl
- constructDecl = None
- if nullable:
- holderType = CGWrapper(holderType, pre="Maybe<", post=" >")
- constructHolder = CGGeneric("${holderName}.construct(%s.SetValue());" % mutableDecl)
- else:
- constructHolder = CGWrapper(holderType, post=" ${holderName}(${declName});")
- holderType = None
-
- templateBody = CGList([constructHolder, templateBody], "\n")
- if nullable:
- if defaultValue:
- assert(isinstance(defaultValue, IDLNullValue))
- valueMissing = "!(${haveValue}) || "
- else:
- valueMissing = ""
- templateBody = handleNull(templateBody, mutableDecl,
- extraConditionForNull=valueMissing)
- templateBody = CGList([constructDecl, templateBody], "\n")
-
- return templateBody.define(), declType, holderType, False
-
- if type.isGeckoInterface():
- assert not isEnforceRange and not isClamp
-
- descriptor = descriptorProvider.getDescriptor(
- type.unroll().inner.identifier.name)
- # This is an interface that we implement as a concrete class
- # or an XPCOM interface.
-
- # Allow null pointers for nullable types and old-binding classes
- argIsPointer = type.nullable() or type.unroll().inner.isExternal()
-
- # Sequences and non-worker callbacks have to hold a strong ref to the
- # thing being passed down.
- forceOwningType = (descriptor.interface.isCallback() and
- not descriptor.workers) or isMember
-
- typeName = descriptor.nativeType
- typePtr = typeName + "*"
-
- # Compute a few things:
- # - declType is the type we want to return as the first element of our
- # tuple.
- # - holderType is the type we want to return as the third element
- # of our tuple.
-
- # Set up some sensible defaults for these things insofar as we can.
- holderType = None
- if argIsPointer:
- if forceOwningType:
- declType = "nsRefPtr<" + typeName + ">"
- else:
- declType = typePtr
- else:
- if forceOwningType:
- declType = "OwningNonNull<" + typeName + ">"
- else:
- declType = "NonNull<" + typeName + ">"
-
- templateBody = ""
- if descriptor.castable:
- if descriptor.prefable:
- raise TypeError("We don't support prefable castable object "
- "arguments (like %s), because we don't know "
- "how to handle them being preffed off" %
- descriptor.interface.identifier.name)
- if descriptor.interface.isConsequential():
- raise TypeError("Consequential interface %s being used as an "
- "argument but flagged as castable" %
- descriptor.interface.identifier.name)
- if failureCode is not None:
- templateBody += str(CastableObjectUnwrapper(
- descriptor,
- "&${val}.toObject()",
- "${declName}",
- failureCode))
- else:
- templateBody += str(FailureFatalCastableObjectUnwrapper(
- descriptor,
- "&${val}.toObject()",
- "${declName}"))
- elif descriptor.interface.isCallback():
- templateBody += str(CallbackObjectUnwrapper(
- descriptor,
- "&${val}.toObject()",
- "${declName}",
- codeOnFailure=failureCode))
- elif descriptor.workers:
- templateBody += "${declName} = &${val}.toObject();"
- else:
- # Either external, or new-binding non-castable. We always have a
- # holder for these, because we don't actually know whether we have
- # to addref when unwrapping or not. So we just pass an
- # getter_AddRefs(nsRefPtr) to XPConnect and if we'll need a release
- # it'll put a non-null pointer in there.
- if forceOwningType:
- # Don't return a holderType in this case; our declName
- # will just own stuff.
- templateBody += "nsRefPtr<" + typeName + "> ${holderName};\n"
- else:
- holderType = "nsRefPtr<" + typeName + ">"
- templateBody += (
- "jsval tmpVal = ${val};\n" +
- typePtr + " tmp;\n"
- "if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, static_cast<" + typeName + "**>(getter_AddRefs(${holderName})), &tmpVal))) {\n")
- templateBody += CGIndenter(onFailureBadType(failureCode,
- descriptor.interface.identifier.name)).define()
- templateBody += ("}\n"
- "MOZ_ASSERT(tmp);\n")
-
- if not isDefinitelyObject:
- # Our tmpVal will go out of scope, so we can't rely on it
- # for rooting
- templateBody += (
- "if (tmpVal != ${val} && !${holderName}) {\n"
- " // We have to have a strong ref, because we got this off\n"
- " // some random object that might get GCed\n"
- " ${holderName} = tmp;\n"
- "}\n")
-
- # And store our tmp, before it goes out of scope.
- templateBody += "${declName} = tmp;"
-
- templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
- type, "${declName} = NULL",
- failureCode)
-
- declType = CGGeneric(declType)
- if holderType is not None:
- holderType = CGGeneric(holderType)
- return (templateBody, declType, holderType, isOptional)
-
- if type.isSpiderMonkeyInterface():
- assert not isEnforceRange and not isClamp
- if isMember:
- raise TypeError("Can't handle member arraybuffers or "
- "arraybuffer views because making sure all the "
- "objects are properly rooted is hard")
- name = type.name
- # By default, we use a Maybe<> to hold our typed array. And in the optional
- # non-nullable case we want to pass Optional<TypedArray> to consumers, not
- # Optional<NonNull<TypedArray> >, so jump though some hoops to do that.
- holderType = "Maybe<%s>" % name
- constructLoc = "${holderName}"
- constructMethod = "construct"
- constructInternal = "ref"
- if type.nullable():
- if isOptional:
- declType = "const Optional<" + name + "*>"
- else:
- declType = name + "*"
- else:
- if isOptional:
- declType = "const Optional<" + name + ">"
- # We don't need a holder in this case
- holderType = None
- constructLoc = "(const_cast<Optional<" + name + ">& >(${declName}))"
- constructMethod = "Construct"
- constructInternal = "Value"
- else:
- declType = "NonNull<" + name + ">"
- template = (
- "%s.%s(cx, &${val}.toObject());\n"
- "if (!%s.%s().inited()) {\n"
- "%s" # No newline here because onFailureBadType() handles that
- "}\n" %
- (constructLoc, constructMethod, constructLoc, constructInternal,
- CGIndenter(onFailureBadType(failureCode, type.name)).define()))
- nullableTarget = ""
- if type.nullable():
- if isOptional:
- mutableDecl = "(const_cast<Optional<" + name + "*>& >(${declName}))"
- template += "%s.Construct();\n" % mutableDecl
- nullableTarget = "%s.Value()" % mutableDecl
- else:
- nullableTarget = "${declName}"
- template += "%s = ${holderName}.addr();" % nullableTarget
- elif not isOptional:
- template += "${declName} = ${holderName}.addr();"
- template = wrapObjectTemplate(template, isDefinitelyObject, type,
- "%s = NULL" % nullableTarget,
- failureCode)
-
- if holderType is not None:
- holderType = CGGeneric(holderType)
- # We handle all the optional stuff ourselves; no need for caller to do it.
- return (template, CGGeneric(declType), holderType, False)
-
- if type.isString():
- assert not isEnforceRange and not isClamp
-
- treatAs = {
- "Default": "eStringify",
- "EmptyString": "eEmpty",
- "Null": "eNull"
- }
- if type.nullable():
- # For nullable strings null becomes a null string.
- treatNullAs = "Null"
- # For nullable strings undefined becomes a null string unless
- # specified otherwise.
- if treatUndefinedAs == "Default":
- treatUndefinedAs = "Null"
- nullBehavior = treatAs[treatNullAs]
- if treatUndefinedAs == "Missing":
- raise TypeError("We don't support [TreatUndefinedAs=Missing]")
- undefinedBehavior = treatAs[treatUndefinedAs]
-
- def getConversionCode(varName):
- conversionCode = (
- "if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, %s)) {\n"
- " return false;\n"
- "}" % (nullBehavior, undefinedBehavior, varName))
- if defaultValue is None:
- return conversionCode
-
- if isinstance(defaultValue, IDLNullValue):
- assert(type.nullable())
- return handleDefault(conversionCode,
- "%s.SetNull()" % varName)
- return handleDefault(
- conversionCode,
- ("static const PRUnichar data[] = { %s };\n"
- "%s.SetData(data, ArrayLength(data) - 1)" %
- (", ".join(["'" + char + "'" for char in defaultValue.value] + ["0"]),
- varName)))
-
- if isMember:
- # We have to make a copy, because our jsval may well not
- # live as long as our string needs to.
- declType = CGGeneric("nsString")
- return (
- "{\n"
- " FakeDependentString str;\n"
- "%s\n"
- " ${declName} = str;\n"
- "}\n" % CGIndenter(CGGeneric(getConversionCode("str"))).define(),
- declType, None, isOptional)
-
- if isOptional:
- declType = "Optional<nsAString>"
- else:
- declType = "NonNull<nsAString>"
-
- return (
- "%s\n"
- "const_cast<%s&>(${declName}) = &${holderName};" %
- (getConversionCode("${holderName}"), declType),
- CGGeneric("const " + declType), CGGeneric("FakeDependentString"),
- # No need to deal with Optional here; we have handled it already
- False)
-
- if type.isEnum():
- assert not isEnforceRange and not isClamp
-
- if type.nullable():
- raise TypeError("We don't support nullable enumerated arguments "
- "yet")
- enum = type.inner.identifier.name
- if invalidEnumValueFatal:
- handleInvalidEnumValueCode = " MOZ_ASSERT(index >= 0);\n"
- else:
- handleInvalidEnumValueCode = (
- " if (index < 0) {\n"
- " return true;\n"
- " }\n")
-
- template = (
- "{\n"
- " bool ok;\n"
- " int index = FindEnumStringIndex<%(invalidEnumValueFatal)s>(cx, ${val}, %(values)s, \"%(enumtype)s\", &ok);\n"
- " if (!ok) {\n"
- " return false;\n"
- " }\n"
- "%(handleInvalidEnumValueCode)s"
- " ${declName} = static_cast<%(enumtype)s>(index);\n"
- "}" % { "enumtype" : enum,
- "values" : enum + "Values::strings",
- "invalidEnumValueFatal" : toStringBool(invalidEnumValueFatal),
- "handleInvalidEnumValueCode" : handleInvalidEnumValueCode })
-
- if defaultValue is not None:
- assert(defaultValue.type.tag() == IDLType.Tags.domstring)
- template = handleDefault(template,
- ("${declName} = %sValues::%s" %
- (enum,
- getEnumValueName(defaultValue.value))))
- return (template, CGGeneric(enum), None, isOptional)
-
- if type.isCallback():
- assert not isEnforceRange and not isClamp
-
- if isMember:
- raise TypeError("Can't handle member callbacks; need to sort out "
- "rooting issues")
- # XXXbz we're going to assume that callback types are always
- # nullable and always have [TreatNonCallableAsNull] for now.
- haveCallable = "${val}.isObject() && JS_ObjectIsCallable(cx, &${val}.toObject())"
- if defaultValue is not None:
- assert(isinstance(defaultValue, IDLNullValue))
- haveCallable = "${haveValue} && " + haveCallable
- return (
- "if (%s) {\n"
- " ${declName} = &${val}.toObject();\n"
- "} else {\n"
- " ${declName} = NULL;\n"
- "}" % haveCallable,
- CGGeneric("JSObject*"), None, isOptional)
-
- if type.isAny():
- assert not isEnforceRange and not isClamp
-
- if isMember:
- raise TypeError("Can't handle member 'any'; need to sort out "
- "rooting issues")
- templateBody = "${declName} = ${val};"
- templateBody = handleDefaultNull(templateBody,
- "${declName} = JS::NullValue()")
- return (templateBody, CGGeneric("JS::Value"), None, isOptional)
-
- if type.isObject():
- assert not isEnforceRange and not isClamp
-
- if isMember:
- raise TypeError("Can't handle member 'object'; need to sort out "
- "rooting issues")
- template = wrapObjectTemplate("${declName} = &${val}.toObject();",
- isDefinitelyObject, type,
- "${declName} = NULL",
- failureCode)
- if type.nullable():
- declType = CGGeneric("JSObject*")
- else:
- declType = CGGeneric("NonNull<JSObject>")
- return (template, declType, None, isOptional)
-
- if type.isDictionary():
- if failureCode is not None:
- raise TypeError("Can't handle dictionaries when failureCode is not None")
- # There are no nullable dictionaries
- assert not type.nullable()
- # All optional dictionaries always have default values, so we
- # should be able to assume not isOptional here.
- assert not isOptional
-
- typeName = CGDictionary.makeDictionaryName(type.inner,
- descriptorProvider.workers)
- actualTypeName = typeName
- selfRef = "${declName}"
-
- declType = CGGeneric(actualTypeName)
-
- # If we're a member of something else, the const
- # will come from the Optional or our container.
- if not isMember:
- declType = CGWrapper(declType, pre="const ")
- selfRef = "const_cast<%s&>(%s)" % (typeName, selfRef)
-
- # We do manual default value handling here, because we
- # actually do want a jsval, and we only handle null anyway
- if defaultValue is not None:
- assert(isinstance(defaultValue, IDLNullValue))
- val = "(${haveValue}) ? ${val} : JSVAL_NULL"
- else:
- val = "${val}"
-
- template = ("if (!%s.Init(cx, %s)) {\n"
- " return false;\n"
- "}" % (selfRef, val))
-
- return (template, declType, None, False)
-
- if not type.isPrimitive():
- raise TypeError("Need conversion for argument type '%s'" % str(type))
-
- typeName = builtinNames[type.tag()]
-
- conversionBehavior = "eDefault"
- if isEnforceRange:
- conversionBehavior = "eEnforceRange"
- elif isClamp:
- conversionBehavior = "eClamp"
-
- if type.nullable():
- dataLoc = "${declName}.SetValue()"
- nullCondition = "${val}.isNullOrUndefined()"
- if defaultValue is not None and isinstance(defaultValue, IDLNullValue):
- nullCondition = "!(${haveValue}) || " + nullCondition
- template = (
- "if (%s) {\n"
- " ${declName}.SetNull();\n"
- "} else if (!ValueToPrimitive<%s, %s>(cx, ${val}, &%s)) {\n"
- " return false;\n"
- "}" % (nullCondition, typeName, conversionBehavior, dataLoc))
- declType = CGGeneric("Nullable<" + typeName + ">")
- else:
- assert(defaultValue is None or
- not isinstance(defaultValue, IDLNullValue))
- dataLoc = "${declName}"
- template = (
- "if (!ValueToPrimitive<%s, %s>(cx, ${val}, &%s)) {\n"
- " return false;\n"
- "}" % (typeName, conversionBehavior, dataLoc))
- declType = CGGeneric(typeName)
- if (defaultValue is not None and
- # We already handled IDLNullValue, so just deal with the other ones
- not isinstance(defaultValue, IDLNullValue)):
- tag = defaultValue.type.tag()
- if tag in numericTags:
- defaultStr = defaultValue.value
- else:
- assert(tag == IDLType.Tags.bool)
- defaultStr = toStringBool(defaultValue.value)
- template = CGWrapper(CGIndenter(CGGeneric(template)),
- pre="if (${haveValue}) {\n",
- post=("\n"
- "} else {\n"
- " %s = %s;\n"
- "}" % (dataLoc, defaultStr))).define()
-
- return (template, declType, None, isOptional)
-
-def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
- argcAndIndex=None):
- """
- Take a tuple as returned by getJSToNativeConversionTemplate and a set of
- replacements as required by the strings in such a tuple, and generate code
- to convert into stack C++ types.
-
- If argcAndIndex is not None it must be a dict that can be used to
- replace ${argc} and ${index}, where ${index} is the index of this
- argument (0-based) and ${argc} is the total number of arguments.
- """
- (templateBody, declType, holderType, dealWithOptional) = templateTuple
-
- if dealWithOptional and argcAndIndex is None:
- raise TypeError("Have to deal with optional things, but don't know how")
- if argcAndIndex is not None and declType is None:
- raise TypeError("Need to predeclare optional things, so they will be "
- "outside the check for big enough arg count!");
-
- result = CGList([], "\n")
- # Make a copy of "replacements" since we may be about to start modifying it
- replacements = dict(replacements)
- originalHolderName = replacements["holderName"]
- if holderType is not None:
- if dealWithOptional:
- replacements["holderName"] = (
- "const_cast< %s & >(%s.Value())" %
- (holderType.define(), originalHolderName))
- mutableHolderType = CGWrapper(holderType, pre="Optional< ", post=" >")
- holderType = CGWrapper(mutableHolderType, pre="const ")
- result.append(
- CGList([holderType, CGGeneric(" "),
- CGGeneric(originalHolderName),
- CGGeneric(";")]))
-
- originalDeclName = replacements["declName"]
- if declType is not None:
- if dealWithOptional:
- replacements["declName"] = (
- "const_cast< %s & >(%s.Value())" %
- (declType.define(), originalDeclName))
- mutableDeclType = CGWrapper(declType, pre="Optional< ", post=" >")
- declType = CGWrapper(mutableDeclType, pre="const ")
- result.append(
- CGList([declType, CGGeneric(" "),
- CGGeneric(originalDeclName),
- CGGeneric(";")]))
-
- conversion = CGGeneric(
- string.Template(templateBody).substitute(replacements)
- )
-
- if argcAndIndex is not None:
- if dealWithOptional:
- declConstruct = CGIndenter(
- CGGeneric("const_cast< %s &>(%s).Construct();" %
- (mutableDeclType.define(), originalDeclName)))
- if holderType is not None:
- holderConstruct = CGIndenter(
- CGGeneric("const_cast< %s &>(%s).Construct();" %
- (mutableHolderType.define(), originalHolderName)))
- else:
- holderConstruct = None
- else:
- declConstruct = None
- holderConstruct = None
-
- conversion = CGList(
- [CGGeneric(
- string.Template("if (${index} < ${argc}) {").substitute(
- argcAndIndex
- )),
- declConstruct,
- holderConstruct,
- CGIndenter(conversion),
- CGGeneric("}")],
- "\n")
-
- result.append(conversion)
- # Add an empty CGGeneric to get an extra newline after the argument
- # conversion.
- result.append(CGGeneric(""))
- return result;
-
-def convertConstIDLValueToJSVal(value):
- if isinstance(value, IDLNullValue):
- return "JSVAL_NULL"
- tag = value.type.tag()
- if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
- IDLType.Tags.uint16, IDLType.Tags.int32]:
- return "INT_TO_JSVAL(%s)" % (value.value)
- if tag == IDLType.Tags.uint32:
- return "UINT_TO_JSVAL(%s)" % (value.value)
- if tag in [IDLType.Tags.int64, IDLType.Tags.uint64]:
- return "DOUBLE_TO_JSVAL(%s)" % (value.value)
- if tag == IDLType.Tags.bool:
- return "JSVAL_TRUE" if value.value else "JSVAL_FALSE"
- if tag in [IDLType.Tags.float, IDLType.Tags.double]:
- return "DOUBLE_TO_JSVAL(%s)" % (value.value)
- raise TypeError("Const value of unhandled type: " + value.type)
-
-class CGArgumentConverter(CGThing):
- """
- A class that takes an IDL argument object, its index in the
- argument list, and the argv and argc strings and generates code to
- unwrap the argument to the right native type.
- """
- def __init__(self, argument, index, argv, argc, descriptorProvider,
- invalidEnumValueFatal=True):
- CGThing.__init__(self)
- self.argument = argument
- if argument.variadic:
- raise TypeError("We don't support variadic arguments yet " +
- str(argument.location))
- assert(not argument.defaultValue or argument.optional)
-
- replacer = {
- "index" : index,
- "argc" : argc,
- "argv" : argv
- }
- self.replacementVariables = {
- "declName" : "arg%d" % index,
- "holderName" : ("arg%d" % index) + "_holder"
- }
- self.replacementVariables["val"] = string.Template(
- "${argv}[${index}]"
- ).substitute(replacer)
- self.replacementVariables["valPtr"] = (
- "&" + self.replacementVariables["val"])
- if argument.defaultValue:
- self.replacementVariables["haveValue"] = string.Template(
- "${index} < ${argc}").substitute(replacer)
- self.descriptorProvider = descriptorProvider
- if self.argument.optional and not self.argument.defaultValue:
- self.argcAndIndex = replacer
- else:
- self.argcAndIndex = None
- self.invalidEnumValueFatal = invalidEnumValueFatal
-
- def define(self):
- return instantiateJSToNativeConversionTemplate(
- getJSToNativeConversionTemplate(self.argument.type,
- self.descriptorProvider,
- isOptional=(self.argcAndIndex is not None),
- invalidEnumValueFatal=self.invalidEnumValueFatal,
- defaultValue=self.argument.defaultValue,
- treatNullAs=self.argument.treatNullAs,
- treatUndefinedAs=self.argument.treatUndefinedAs,
- isEnforceRange=self.argument.enforceRange,
- isClamp=self.argument.clamp),
- self.replacementVariables,
- self.argcAndIndex).define()
-
-def getWrapTemplateForType(type, descriptorProvider, result, successCode,
- isCreator):
- """
- Reflect a C++ value stored in "result", of IDL type "type" into JS. The
- "successCode" is the code to run once we have successfully done the
- conversion. The resulting string should be used with string.Template, it
- needs the following keys when substituting: jsvalPtr/jsvalRef/obj.
-
- Returns (templateString, infallibility of conversion template)
- """
- haveSuccessCode = successCode is not None
- if not haveSuccessCode:
- successCode = "return true;"
-
- def setValue(value, callWrapValue=False):
- """
- Returns the code to set the jsval to value. If "callWrapValue" is true
- JS_WrapValue will be called on the jsval.
- """
- if not callWrapValue:
- tail = successCode
- elif haveSuccessCode:
- tail = ("if (!JS_WrapValue(cx, ${jsvalPtr})) {\n" +
- " return false;\n" +
- "}\n" +
- successCode)
- else:
- tail = "return JS_WrapValue(cx, ${jsvalPtr});"
- return ("${jsvalRef} = %s;\n" +
- tail) % (value)
-
- def wrapAndSetPtr(wrapCall, failureCode=None):
- """
- Returns the code to set the jsval by calling "wrapCall". "failureCode"
- is the code to run if calling "wrapCall" fails
- """
- if failureCode is None:
- if not haveSuccessCode:
- return "return " + wrapCall + ";"
- failureCode = "return false;"
- str = ("if (!%s) {\n" +
- CGIndenter(CGGeneric(failureCode)).define() + "\n" +
- "}\n" +
- successCode) % (wrapCall)
- return str
-
- if type is None or type.isVoid():
- return (setValue("JSVAL_VOID"), True)
-
- if type.isArray():
- raise TypeError("Can't handle array return values yet")
-
- if type.isSequence():
- if type.nullable():
- # Nullable sequences are Nullable< nsTArray<T> >
- (recTemplate, recInfall) = getWrapTemplateForType(type.inner, descriptorProvider,
- "%s.Value()" % result, successCode,
- isCreator)
- return ("""
-if (%s.IsNull()) {
-%s
-}
-%s""" % (result, CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define(), recTemplate), recInfall)
-
- # Now do non-nullable sequences. We use setting the element
- # in the array as our succcess code because when we succeed in
- # wrapping that's what we should do.
- innerTemplate = wrapForType(
- type.inner, descriptorProvider,
- {
- 'result' : "%s[i]" % result,
- 'successCode': ("if (!JS_DefineElement(cx, returnArray, i, tmp,\n"
- " NULL, NULL, JSPROP_ENUMERATE)) {\n"
- " return false;\n"
- "}"),
- 'jsvalRef': "tmp",
- 'jsvalPtr': "&tmp",
- 'isCreator': isCreator
- }
- )
- innerTemplate = CGIndenter(CGGeneric(innerTemplate)).define()
- return (("""
-uint32_t length = %s.Length();
-JSObject *returnArray = JS_NewArrayObject(cx, length, NULL);
-if (!returnArray) {
- return false;
-}
-jsval tmp;
-for (uint32_t i = 0; i < length; ++i) {
-%s
-}\n""" % (result, innerTemplate)) + setValue("JS::ObjectValue(*returnArray)"), False)
-
- if type.isGeckoInterface():
- descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
- if type.nullable():
- wrappingCode = ("if (!%s) {\n" % (result) +
- CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
- "}\n")
- else:
- wrappingCode = ""
- if (not descriptor.interface.isExternal() and
- not descriptor.interface.isCallback()):
- if descriptor.wrapperCache:
- wrapMethod = "WrapNewBindingObject"
- else:
- if not isCreator:
- raise MethodNotCreatorError(descriptor.interface.identifier.name)
- wrapMethod = "WrapNewBindingNonWrapperCachedObject"
- wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, result)
- # We don't support prefable stuff in workers.
- assert(not descriptor.prefable or not descriptor.workers)
- if not descriptor.prefable:
- # Non-prefable bindings can only fail to wrap as a new-binding object
- # if they already threw an exception. Same thing for
- # non-prefable bindings.
- failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
- "return false;")
- else:
- if descriptor.notflattened:
- raise TypeError("%s is prefable but not flattened; "
- "fallback won't work correctly" %
- descriptor.interface.identifier.name)
- # Try old-style wrapping for bindings which might be preffed off.
- failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result)
- wrappingCode += wrapAndSetPtr(wrap, failed)
- else:
- if descriptor.notflattened:
- getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
- else:
- getIID = ""
- wrap = "WrapObject(cx, ${obj}, %s, %s${jsvalPtr})" % (result, getIID)
- wrappingCode += wrapAndSetPtr(wrap)
- return (wrappingCode, False)
-
- if type.isString():
- if type.nullable():
- return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalPtr})" % result), False)
- else:
- return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalPtr})" % result), False)
-
- if type.isEnum():
- if type.nullable():
- raise TypeError("We don't support nullable enumerated return types "
- "yet")
- return ("""MOZ_ASSERT(uint32_t(%(result)s) < ArrayLength(%(strings)s));
-JSString* %(resultStr)s = JS_NewStringCopyN(cx, %(strings)s[uint32_t(%(result)s)].value, %(strings)s[uint32_t(%(result)s)].length);
-if (!%(resultStr)s) {
- return false;
-}
-""" % { "result" : result,
- "resultStr" : result + "_str",
- "strings" : type.inner.identifier.name + "Values::strings" } +
- setValue("JS::StringValue(%s_str)" % result), False)
-
- if type.isCallback():
- assert not type.isInterface()
- # XXXbz we're going to assume that callback types are always
- # nullable and always have [TreatNonCallableAsNull] for now.
- # See comments in WrapNewBindingObject explaining why we need
- # to wrap here.
- # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
- return (setValue("JS::ObjectOrNullValue(%s)" % result, True), False)
-
- if type.tag() == IDLType.Tags.any:
- # See comments in WrapNewBindingObject explaining why we need
- # to wrap here.
- # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
- return (setValue(result, True), False)
-
- if type.isObject() or type.isSpiderMonkeyInterface():
- # See comments in WrapNewBindingObject explaining why we need
- # to wrap here.
- if type.nullable():
- toValue = "JS::ObjectOrNullValue(%s)"
- else:
- toValue = "JS::ObjectValue(*%s)"
- # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
- return (setValue(toValue % result, True), False)
-
- if not type.isPrimitive():
- raise TypeError("Need to learn to wrap %s" % type)
-
- if type.nullable():
- (recTemplate, recInfal) = getWrapTemplateForType(type.inner, descriptorProvider,
- "%s.Value()" % result, successCode,
- isCreator)
- return ("if (%s.IsNull()) {\n" % result +
- CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
- "}\n" + recTemplate, recInfal)
-
- tag = type.tag()
-
- if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
- IDLType.Tags.uint16, IDLType.Tags.int32]:
- return (setValue("INT_TO_JSVAL(int32_t(%s))" % result), True)
-
- elif tag in [IDLType.Tags.int64, IDLType.Tags.uint64, IDLType.Tags.float,
- IDLType.Tags.double]:
- # XXXbz will cast to double do the "even significand" thing that webidl
- # calls for for 64-bit ints? Do we care?
- return (setValue("JS_NumberValue(double(%s))" % result), True)
-
- elif tag == IDLType.Tags.uint32:
- return (setValue("UINT_TO_JSVAL(%s)" % result), True)
-
- elif tag == IDLType.Tags.bool:
- return (setValue("BOOLEAN_TO_JSVAL(%s)" % result), True)
-
- else:
- raise TypeError("Need to learn to wrap primitive: %s" % type)
-
-def wrapForType(type, descriptorProvider, templateValues):
- """
- Reflect a C++ value of IDL type "type" into JS. TemplateValues is a dict
- that should contain:
-
- * 'jsvalRef': a C++ reference to the jsval in which to store the result of
- the conversion
- * 'jsvalPtr': a C++ pointer to the jsval in which to store the result of
- the conversion
- * 'obj' (optional): the name of the variable that contains the JSObject to
- use as a scope when wrapping, if not supplied 'obj'
- will be used as the name
- * 'result' (optional): the name of the variable in which the C++ value is
- stored, if not supplied 'result' will be used as
- the name
- * 'successCode' (optional): the code to run once we have successfully done
- the conversion, if not supplied 'return true;'
- will be used as the code
- * 'isCreator' (optional): If true, we're wrapping for the return value of
- a [Creator] method. Assumed false if not set.
- """
- wrap = getWrapTemplateForType(type, descriptorProvider,
- templateValues.get('result', 'result'),
- templateValues.get('successCode', None),
- templateValues.get('isCreator', False))[0]
-
- defaultValues = {'obj': 'obj'}
- return string.Template(wrap).substitute(defaultValues, **templateValues)
-
-def infallibleForMember(member, type, descriptorProvider):
- """
- Determine the fallibility of changing a C++ value of IDL type "type" into
- JS for the given attribute. Apart from isCreator, all the defaults are used,
- since the fallbility does not change based on the boolean values,
- and the template will be discarded.
-
- CURRENT ASSUMPTIONS:
- We assume that successCode for wrapping up return values cannot contain
- failure conditions.
- """
- return getWrapTemplateForType(type, descriptorProvider, 'result', None,\
- memberIsCreator(member))[1]
-
-def typeNeedsCx(type, retVal=False):
- if type is None:
- return False
- if type.nullable():
- type = type.inner
- if type.isSequence() or type.isArray():
- type = type.inner
- if type.isUnion():
- return any(typeNeedsCx(t) for t in type.unroll().flatMemberTypes)
- if retVal and type.isSpiderMonkeyInterface():
- return True
- return type.isCallback() or type.isAny() or type.isObject()
-
-# Returns a tuple consisting of a CGThing containing the type of the return
-# value, or None if there is no need for a return value, and a boolean signaling
-# whether the return value is passed in an out parameter.
-def getRetvalDeclarationForType(returnType, descriptorProvider,
- resultAlreadyAddRefed):
- if returnType is None or returnType.isVoid():
- # Nothing to declare
- return None, False
- if returnType.isPrimitive() and returnType.tag() in builtinNames:
- result = CGGeneric(builtinNames[returnType.tag()])
- if returnType.nullable():
- result = CGWrapper(result, pre="Nullable<", post=">")
- return result, False
- if returnType.isString():
- return CGGeneric("nsString"), True
- if returnType.isEnum():
- if returnType.nullable():
- raise TypeError("We don't support nullable enum return values")
- return CGGeneric(returnType.inner.identifier.name), False
- if returnType.isGeckoInterface():
- result = CGGeneric(descriptorProvider.getDescriptor(
- returnType.unroll().inner.identifier.name).nativeType)
- if resultAlreadyAddRefed:
- result = CGWrapper(result, pre="nsRefPtr<", post=">")
- else:
- result = CGWrapper(result, post="*")
- return result, False
- if returnType.isCallback():
- # XXXbz we're going to assume that callback types are always
- # nullable for now.
- return CGGeneric("JSObject*"), False
- if returnType.isAny():
- return CGGeneric("JS::Value"), False
- if returnType.isObject() or returnType.isSpiderMonkeyInterface():
- return CGGeneric("JSObject*"), False
- if returnType.isSequence():
- nullable = returnType.nullable()
- if nullable:
- returnType = returnType.inner
- # If our result is already addrefed, use the right type in the
- # sequence argument here.
- (result, _) = getRetvalDeclarationForType(returnType.inner,
- descriptorProvider,
- resultAlreadyAddRefed)
- result = CGWrapper(result, pre="nsTArray< ", post=" >")
- if nullable:
- result = CGWrapper(result, pre="Nullable< ", post=" >")
- return result, True
- raise TypeError("Don't know how to declare return value for %s" %
- returnType)
-
-def isResultAlreadyAddRefed(descriptor, extendedAttributes):
- # Default to already_AddRefed on the main thread, raw pointer in workers
- return not descriptor.workers and not 'resultNotAddRefed' in extendedAttributes
-
-class CGCallGenerator(CGThing):
- """
- A class to generate an actual call to a C++ object. Assumes that the C++
- object is stored in a variable whose name is given by the |object| argument.
-
- errorReport should be a CGThing for an error report or None if no
- error reporting is needed.
- """
- def __init__(self, errorReport, arguments, argsPre, returnType,
- extendedAttributes, descriptorProvider, nativeMethodName,
- static, object="self", declareResult=True):
- CGThing.__init__(self)
-
- assert errorReport is None or isinstance(errorReport, CGThing)
-
- isFallible = errorReport is not None
-
- resultAlreadyAddRefed = isResultAlreadyAddRefed(descriptorProvider,
- extendedAttributes)
- (result, resultOutParam) = getRetvalDeclarationForType(returnType,
- descriptorProvider,
- resultAlreadyAddRefed)
-
- args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
- for (a, name) in arguments:
- # This is a workaround for a bug in Apple's clang.
- if a.type.isObject() and not a.type.nullable() and not a.optional:
- name = "(JSObject&)" + name
- args.append(CGGeneric(name))
-
- # Return values that go in outparams go here
- if resultOutParam:
- args.append(CGGeneric("result"))
- if isFallible:
- args.append(CGGeneric("rv"))
-
- needsCx = (typeNeedsCx(returnType, True) or
- any(typeNeedsCx(a.type) for (a, _) in arguments) or
- 'implicitJSContext' in extendedAttributes)
-
- if not "cx" in argsPre and needsCx:
- args.prepend(CGGeneric("cx"))
-
- # Build up our actual call
- self.cgRoot = CGList([], "\n")
-
- call = CGGeneric(nativeMethodName)
- if static:
- call = CGWrapper(call, pre="%s::" % descriptorProvider.nativeType)
- else:
- call = CGWrapper(call, pre="%s->" % object)
- call = CGList([call, CGWrapper(args, pre="(", post=");")])
- if result is not None:
- if declareResult:
- result = CGWrapper(result, post=" result;")
- self.cgRoot.prepend(result)
- if not resultOutParam:
- call = CGWrapper(call, pre="result = ")
-
- call = CGWrapper(call)
- self.cgRoot.append(call)
-
- if isFallible:
- self.cgRoot.prepend(CGGeneric("ErrorResult rv;"))
- self.cgRoot.append(CGGeneric("if (rv.Failed()) {"))
- self.cgRoot.append(CGIndenter(errorReport))
- self.cgRoot.append(CGGeneric("}"))
-
- def define(self):
- return self.cgRoot.define()
-
-class MethodNotCreatorError(Exception):
- def __init__(self, typename):
- self.typename = typename
-
-class CGPerSignatureCall(CGThing):
- """
- This class handles the guts of generating code for a particular
- call signature. A call signature consists of four things:
-
- 1) A return type, which can be None to indicate that there is no
- actual return value (e.g. this is an attribute setter) or an
- IDLType if there's an IDL type involved (including |void|).
- 2) An argument list, which is allowed to be empty.
- 3) A name of a native method to call.
- 4) Whether or not this method is static.
-
- We also need to know whether this is a method or a getter/setter
- to do error reporting correctly.
-
- The idlNode parameter can be either a method or an attr. We can query
- |idlNode.identifier| in both cases, so we can be agnostic between the two.
- """
- # XXXbz For now each entry in the argument list is either an
- # IDLArgument or a FakeArgument, but longer-term we may want to
- # have ways of flagging things like JSContext* or optional_argc in
- # there.
-
- def __init__(self, returnType, argsPre, arguments, nativeMethodName, static,
- descriptor, idlNode, argConversionStartsAt=0,
- getter=False, setter=False):
- CGThing.__init__(self)
- self.returnType = returnType
- self.descriptor = descriptor
- self.idlNode = idlNode
- self.extendedAttributes = descriptor.getExtendedAttributes(idlNode,
- getter=getter,
- setter=setter)
- self.argsPre = argsPre
- self.arguments = arguments
- self.argCount = len(arguments)
- if self.argCount > argConversionStartsAt:
- # Insert our argv in there
- cgThings = [CGGeneric(self.getArgvDecl())]
- else:
- cgThings = []
- cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgv(),
- self.getArgc(), self.descriptor,
- invalidEnumValueFatal=not setter) for
- i in range(argConversionStartsAt, self.argCount)])
-
- cgThings.append(CGCallGenerator(
- self.getErrorReport() if self.isFallible() else None,
- self.getArguments(), self.argsPre, returnType,
- self.extendedAttributes, descriptor, nativeMethodName,
- static))
- self.cgRoot = CGList(cgThings, "\n")
-
- def getArgv(self):
- return "argv" if self.argCount > 0 else ""
- def getArgvDecl(self):
- return "\nJS::Value* argv = JS_ARGV(cx, vp);\n"
- def getArgc(self):
- return "argc"
- def getArguments(self):
- return [(a, "arg" + str(i)) for (i, a) in enumerate(self.arguments)]
-
- def isFallible(self):
- return not 'infallible' in self.extendedAttributes
-
- def wrap_return_value(self):
- isCreator = memberIsCreator(self.idlNode)
- if isCreator:
- # We better be returning addrefed things!
- assert(isResultAlreadyAddRefed(self.descriptor,
- self.extendedAttributes) or
- # Workers use raw pointers for new-object return
- # values or something
- self.descriptor.workers)
-
- resultTemplateValues = { 'jsvalRef': '*vp', 'jsvalPtr': 'vp',
- 'isCreator': isCreator}
- try:
- return wrapForType(self.returnType, self.descriptor,
- resultTemplateValues)
- except MethodNotCreatorError, err:
- assert not isCreator
- raise TypeError("%s being returned from non-creator method or property %s.%s" %
- (err.typename,
- self.descriptor.interface.identifier.name,
- self.idlNode.identifier.name))
-
- def getErrorReport(self):
- return CGGeneric('return ThrowMethodFailedWithDetails<%s>(cx, rv, "%s", "%s");'
- % (toStringBool(not self.descriptor.workers),
- self.descriptor.interface.identifier.name,
- self.idlNode.identifier.name))
-
- def define(self):
- return (self.cgRoot.define() + "\n" + self.wrap_return_value())
-
-class CGSwitch(CGList):
- """
- A class to generate code for a switch statement.
-
- Takes three constructor arguments: an expression, a list of cases,
- and an optional default.
-
- Each case is a CGCase. The default is a CGThing for the body of
- the default case, if any.
- """
- def __init__(self, expression, cases, default=None):
- CGList.__init__(self, [CGIndenter(c) for c in cases], "\n")
- self.prepend(CGWrapper(CGGeneric(expression),
- pre="switch (", post=") {"));
- if default is not None:
- self.append(
- CGIndenter(
- CGWrapper(
- CGIndenter(default),
- pre="default: {\n",
- post="\n break;\n}"
- )
- )
- )
-
- self.append(CGGeneric("}"))
-
-class CGCase(CGList):
- """
- A class to generate code for a case statement.
-
- Takes three constructor arguments: an expression, a CGThing for
- the body (allowed to be None if there is no body), and an optional
- argument (defaulting to False) for whether to fall through.
- """
- def __init__(self, expression, body, fallThrough=False):
- CGList.__init__(self, [], "\n")
- self.append(CGWrapper(CGGeneric(expression), pre="case ", post=": {"))
- bodyList = CGList([body], "\n")
- if fallThrough:
- bodyList.append(CGGeneric("/* Fall through */"))
- else:
- bodyList.append(CGGeneric("break;"))
- self.append(CGIndenter(bodyList));
- self.append(CGGeneric("}"))
-
-class CGMethodCall(CGThing):
- """
- A class to generate selection of a method signature from a set of
- signatures and generation of a call to that signature.
- """
- def __init__(self, argsPre, nativeMethodName, static, descriptor, method):
- CGThing.__init__(self)
-
- methodName = '"%s.%s"' % (descriptor.interface.identifier.name, method.identifier.name)
-
- def requiredArgCount(signature):
- arguments = signature[1]
- if len(arguments) == 0:
- return 0
- requiredArgs = len(arguments)
- while requiredArgs and arguments[requiredArgs-1].optional:
- requiredArgs -= 1
- return requiredArgs
-
- def getPerSignatureCall(signature, argConversionStartsAt=0):
- return CGPerSignatureCall(signature[0], argsPre, signature[1],
- nativeMethodName, static, descriptor,
- method, argConversionStartsAt)
-
-
- signatures = method.signatures()
- if len(signatures) == 1:
- # Special case: we can just do a per-signature method call
- # here for our one signature and not worry about switching
- # on anything.
- signature = signatures[0]
- self.cgRoot = CGList([ CGIndenter(getPerSignatureCall(signature)) ])
- requiredArgs = requiredArgCount(signature)
-
-
- if requiredArgs > 0:
- code = (
- "if (argc < %d) {\n"
- " return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, %s);\n"
- "}" % (requiredArgs, methodName))
- self.cgRoot.prepend(
- CGWrapper(CGIndenter(CGGeneric(code)), pre="\n", post="\n"))
- return
-
- # Need to find the right overload
- maxArgCount = method.maxArgCount
- allowedArgCounts = method.allowedArgCounts
-
- argCountCases = []
- for argCount in allowedArgCounts:
- possibleSignatures = method.signaturesForArgCount(argCount)
- if len(possibleSignatures) == 1:
- # easy case!
- signature = possibleSignatures[0]
-
- # (possibly) important optimization: if signature[1] has >
- # argCount arguments and signature[1][argCount] is optional and
- # there is only one signature for argCount+1, then the
- # signature for argCount+1 is just ourselves and we can fall
- # through.
- if (len(signature[1]) > argCount and
- signature[1][argCount].optional and
- (argCount+1) in allowedArgCounts and
- len(method.signaturesForArgCount(argCount+1)) == 1):
- argCountCases.append(
- CGCase(str(argCount), None, True))
- else:
- argCountCases.append(
- CGCase(str(argCount), getPerSignatureCall(signature)))
- continue
-
- distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
-
- # We can't handle unions at the distinguishing index.
- for (returnType, args) in possibleSignatures:
- if args[distinguishingIndex].type.isUnion():
- raise TypeError("No support for unions as distinguishing "
- "arguments yet: %s",
- args[distinguishingIndex].location)
-
- # Convert all our arguments up to the distinguishing index.
- # Doesn't matter which of the possible signatures we use, since
- # they all have the same types up to that point; just use
- # possibleSignatures[0]
- caseBody = [CGGeneric("JS::Value* argv_start = JS_ARGV(cx, vp);")]
- caseBody.extend([ CGArgumentConverter(possibleSignatures[0][1][i],
- i, "argv_start", "argc",
- descriptor) for i in
- range(0, distinguishingIndex) ])
-
- # Select the right overload from our set.
- distinguishingArg = "argv_start[%d]" % distinguishingIndex
-
- def pickFirstSignature(condition, filterLambda):
- sigs = filter(filterLambda, possibleSignatures)
- assert len(sigs) < 2
- if len(sigs) > 0:
- if condition is None:
- caseBody.append(
- getPerSignatureCall(sigs[0], distinguishingIndex))
- else:
- caseBody.append(CGGeneric("if (" + condition + ") {"))
- caseBody.append(CGIndenter(
- getPerSignatureCall(sigs[0], distinguishingIndex)))
- caseBody.append(CGGeneric("}"))
- return True
- return False
-
- # First check for null or undefined
- pickFirstSignature("%s.isNullOrUndefined()" % distinguishingArg,
- lambda s: (s[1][distinguishingIndex].type.nullable() or
- s[1][distinguishingIndex].type.isDictionary()))
-
- # Now check for distinguishingArg being an object that implements a
- # non-callback interface. That includes typed arrays and
- # arraybuffers.
- interfacesSigs = [
- s for s in possibleSignatures
- if (s[1][distinguishingIndex].type.isObject() or
- s[1][distinguishingIndex].type.isNonCallbackInterface()) ]
- # There might be more than one of these; we need to check
- # which ones we unwrap to.
-
- if len(interfacesSigs) > 0:
- # The spec says that we should check for "platform objects
- # implementing an interface", but it's enough to guard on these
- # being an object. The code for unwrapping non-callback
- # interfaces and typed arrays will just bail out and move on to
- # the next overload if the object fails to unwrap correctly. We
- # could even not do the isObject() check up front here, but in
- # cases where we have multiple object overloads it makes sense
- # to do it only once instead of for each overload. That will
- # also allow the unwrapping test to skip having to do codegen
- # for the null-or-undefined case, which we already handled
- # above.
- caseBody.append(CGGeneric("if (%s.isObject()) {" %
- (distinguishingArg)))
- for sig in interfacesSigs:
- caseBody.append(CGIndenter(CGGeneric("do {")));
- type = sig[1][distinguishingIndex].type
-
- # The argument at index distinguishingIndex can't possibly
- # be unset here, because we've already checked that argc is
- # large enough that we can examine this argument.
- testCode = instantiateJSToNativeConversionTemplate(
- getJSToNativeConversionTemplate(type, descriptor,
- failureCode="break;",
- isDefinitelyObject=True),
- {
- "declName" : "arg%d" % distinguishingIndex,
- "holderName" : ("arg%d" % distinguishingIndex) + "_holder",
- "val" : distinguishingArg
- })
-
- # Indent by 4, since we need to indent further than our "do" statement
- caseBody.append(CGIndenter(testCode, 4));
- # If we got this far, we know we unwrapped to the right
- # interface, so just do the call. Start conversion with
- # distinguishingIndex + 1, since we already converted
- # distinguishingIndex.
- caseBody.append(CGIndenter(
- getPerSignatureCall(sig, distinguishingIndex + 1), 4))
- caseBody.append(CGIndenter(CGGeneric("} while (0);")))
-
- caseBody.append(CGGeneric("}"))
-
- # XXXbz Now we're supposed to check for distinguishingArg being
- # an array or a platform object that supports indexed
- # properties... skip that last for now. It's a bit of a pain.
- pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject())" %
- (distinguishingArg, distinguishingArg),
- lambda s:
- (s[1][distinguishingIndex].type.isArray() or
- s[1][distinguishingIndex].type.isSequence() or
- s[1][distinguishingIndex].type.isObject()))
-
- # Check for Date objects
- # XXXbz Do we need to worry about security wrappers around the Date?
- pickFirstSignature("%s.isObject() && JS_ObjectIsDate(cx, &%s.toObject())" %
- (distinguishingArg, distinguishingArg),
- lambda s: (s[1][distinguishingIndex].type.isDate() or
- s[1][distinguishingIndex].type.isObject()))
-
- # Check for vanilla JS objects
- # XXXbz Do we need to worry about security wrappers?
- pickFirstSignature("%s.isObject() && !IsPlatformObject(cx, &%s.toObject())" %
- (distinguishingArg, distinguishingArg),
- lambda s: (s[1][distinguishingIndex].type.isCallback() or
- s[1][distinguishingIndex].type.isCallbackInterface() or
- s[1][distinguishingIndex].type.isDictionary() or
- s[1][distinguishingIndex].type.isObject()))
-
- # The remaining cases are mutually exclusive. The
- # pickFirstSignature calls are what change caseBody
- # Check for strings or enums
- if pickFirstSignature(None,
- lambda s: (s[1][distinguishingIndex].type.isString() or
- s[1][distinguishingIndex].type.isEnum())):
- pass
- # Check for primitives
- elif pickFirstSignature(None,
- lambda s: s[1][distinguishingIndex].type.isPrimitive()):
- pass
- # Check for "any"
- elif pickFirstSignature(None,
- lambda s: s[1][distinguishingIndex].type.isAny()):
- pass
- else:
- # Just throw; we have no idea what we're supposed to
- # do with this.
- caseBody.append(CGGeneric("return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);" %
- toStringBool(not descriptor.workers)))
-
- argCountCases.append(CGCase(str(argCount),
- CGList(caseBody, "\n")))
-
- overloadCGThings = []
- overloadCGThings.append(
- CGGeneric("unsigned argcount = NS_MIN(argc, %du);" %
- maxArgCount))
- overloadCGThings.append(
- CGSwitch("argcount",
- argCountCases,
- CGGeneric("return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, %s);\n" % methodName)))
- overloadCGThings.append(
- CGGeneric('MOZ_NOT_REACHED("We have an always-returning default case");\n'
- 'return false;'))
- self.cgRoot = CGWrapper(CGIndenter(CGList(overloadCGThings, "\n")),
- pre="\n")
-
- def define(self):
- return self.cgRoot.define()
-
-class CGGetterCall(CGPerSignatureCall):
- """
- A class to generate a native object getter call for a particular IDL
- getter.
- """
- def __init__(self, returnType, nativeMethodName, descriptor, attr):
- CGPerSignatureCall.__init__(self, returnType, [], [],
- nativeMethodName, False, descriptor,
- attr, getter=True)
-
-class FakeArgument():
- """
- A class that quacks like an IDLArgument. This is used to make
- setters look like method calls or for special operations.
- """
- def __init__(self, type, interfaceMember):
- self.type = type
- self.optional = False
- self.variadic = False
- self.defaultValue = None
- self.treatNullAs = interfaceMember.treatNullAs
- self.treatUndefinedAs = interfaceMember.treatUndefinedAs
- self.enforceRange = False
- self.clamp = False
-
-class CGSetterCall(CGPerSignatureCall):
- """
- A class to generate a native object setter call for a particular IDL
- setter.
- """
- def __init__(self, argType, nativeMethodName, descriptor, attr):
- CGPerSignatureCall.__init__(self, None, [],
- [FakeArgument(argType, attr)],
- nativeMethodName, False, descriptor, attr,
- setter=True)
- def wrap_return_value(self):
- # We have no return value
- return "\nreturn true;"
- def getArgc(self):
- return "1"
- def getArgvDecl(self):
- # We just get our stuff from our last arg no matter what
- return ""
-
-class FakeCastableDescriptor():
- def __init__(self, descriptor):
- self.castable = True
- self.workers = descriptor.workers
- self.nativeType = descriptor.nativeType
- self.name = descriptor.name
- self.hasXPConnectImpls = descriptor.hasXPConnectImpls
-
-class CGAbstractBindingMethod(CGAbstractStaticMethod):
- """
- Common class to generate the JSNatives for all our methods, getters, and
- setters. This will generate the function declaration and unwrap the
- |this| object. Subclasses are expected to override the generate_code
- function to do the rest of the work. This function should return a
- CGThing which is already properly indented.
- """
- def __init__(self, descriptor, name, args, unwrapFailureCode=None):
- CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
-
- if unwrapFailureCode is None:
- self.unwrapFailureCode = ("return Throw<%s>(cx, rv);" %
- toStringBool(not descriptor.workers))
- else:
- self.unwrapFailureCode = unwrapFailureCode
-
- def definition_body(self):
- # Our descriptor might claim that we're not castable, simply because
- # we're someone's consequential interface. But for this-unwrapping, we
- # know that we're the real deal. So fake a descriptor here for
- # consumption by FailureFatalCastableObjectUnwrapper.
- unwrapThis = CGIndenter(CGGeneric(
- str(CastableObjectUnwrapper(
- FakeCastableDescriptor(self.descriptor),
- "obj", "self", self.unwrapFailureCode))))
- return CGList([ self.getThis(), unwrapThis,
- self.generate_code() ], "\n").define()
-
- def getThis(self):
- return CGIndenter(
- CGGeneric("js::RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));\n"
- "if (!obj) {\n"
- " return false;\n"
- "}\n"
- "\n"
- "%s* self;" % self.descriptor.nativeType))
-
- def generate_code(self):
- assert(False) # Override me
-
-def MakeNativeName(name):
- return name[0].upper() + name[1:]
-
-class CGGenericMethod(CGAbstractBindingMethod):
- """
- A class for generating the C++ code for an IDL method..
- """
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
- Argument('JS::Value*', 'vp')]
- CGAbstractBindingMethod.__init__(self, descriptor, 'genericMethod', args)
-
- def generate_code(self):
- return CGIndenter(CGGeneric(
- "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "JSJitMethodOp method = (JSJitMethodOp)info->op;\n"
- "return method(cx, obj, self, argc, vp);"))
-
-class CGSpecializedMethod(CGAbstractStaticMethod):
- """
- A class for generating the C++ code for a specialized method that the JIT
- can call with lower overhead.
- """
- def __init__(self, descriptor, method):
- self.method = method
- name = method.identifier.name
- args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
- Argument('%s*' % descriptor.nativeType, 'self'),
- Argument('unsigned', 'argc'), Argument('JS::Value*', 'vp')]
- CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool', args)
-
- def definition_body(self):
- name = self.method.identifier.name
- nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
- return CGMethodCall([], nativeName, self.method.isStatic(),
- self.descriptor, self.method).define()
-
-class CGGenericGetter(CGAbstractBindingMethod):
- """
- A class for generating the C++ code for an IDL attribute getter.
- """
- def __init__(self, descriptor, lenientThis=False):
- args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
- Argument('JS::Value*', 'vp')]
- if lenientThis:
- name = "genericLenientGetter"
- unwrapFailureCode = (
- "MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
- "JS_SET_RVAL(cx, vp, JS::UndefinedValue());\n"
- "return true;")
- else:
- name = "genericGetter"
- unwrapFailureCode = None
- CGAbstractBindingMethod.__init__(self, descriptor, name, args,
- unwrapFailureCode)
-
- def generate_code(self):
- return CGIndenter(CGGeneric(
- "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "JSJitPropertyOp getter = info->op;\n"
- "return getter(cx, obj, self, vp);"))
-
-class CGSpecializedGetter(CGAbstractStaticMethod):
- """
- A class for generating the code for a specialized attribute getter
- that the JIT can call with lower overhead.
- """
- def __init__(self, descriptor, attr):
- self.attr = attr
- name = 'get_' + attr.identifier.name
- args = [ Argument('JSContext*', 'cx'),
- Argument('JSHandleObject', 'obj'),
- Argument('%s*' % descriptor.nativeType, 'self'),
- Argument('JS::Value*', 'vp') ]
- CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
-
- def definition_body(self):
- name = self.attr.identifier.name
- nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
- # resultOutParam does not depend on whether resultAlreadyAddRefed is set
- (_, resultOutParam) = getRetvalDeclarationForType(self.attr.type,
- self.descriptor,
- False)
- infallible = ('infallible' in
- self.descriptor.getExtendedAttributes(self.attr,
- getter=True))
- if resultOutParam or self.attr.type.nullable() or not infallible:
- nativeName = "Get" + nativeName
- return CGIndenter(CGGetterCall(self.attr.type, nativeName,
- self.descriptor, self.attr)).define()
-
-class CGGenericSetter(CGAbstractBindingMethod):
- """
- A class for generating the C++ code for an IDL attribute setter.
- """
- def __init__(self, descriptor, lenientThis=False):
- args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
- Argument('JS::Value*', 'vp')]
- if lenientThis:
- name = "genericLenientSetter"
- unwrapFailureCode = (
- "MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
- "return true;")
- else:
- name = "genericSetter"
- unwrapFailureCode = None
- CGAbstractBindingMethod.__init__(self, descriptor, name, args,
- unwrapFailureCode)
-
- def generate_code(self):
- return CGIndenter(CGGeneric(
- "JS::Value* argv = JS_ARGV(cx, vp);\n"
- "JS::Value undef = JS::UndefinedValue();\n"
- "if (argc == 0) {\n"
- " argv = &undef;\n"
- "}\n"
- "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "JSJitPropertyOp setter = info->op;\n"
- "if (!setter(cx, obj, self, argv)) {\n"
- " return false;\n"
- "}\n"
- "*vp = JSVAL_VOID;\n"
- "return true;"))
-
-class CGSpecializedSetter(CGAbstractStaticMethod):
- """
- A class for generating the code for a specialized attribute setter
- that the JIT can call with lower overhead.
- """
- def __init__(self, descriptor, attr):
- self.attr = attr
- name = 'set_' + attr.identifier.name
- args = [ Argument('JSContext*', 'cx'),
- Argument('JSHandleObject', 'obj'),
- Argument('%s*' % descriptor.nativeType, 'self'),
- Argument('JS::Value*', 'argv')]
- CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
-
- def definition_body(self):
- name = self.attr.identifier.name
- nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
- return CGIndenter(CGSetterCall(self.attr.type, nativeName,
- self.descriptor, self.attr)).define()
-
-def memberIsCreator(member):
- return member.getExtendedAttribute("Creator") is not None
-
-class CGMemberJITInfo(CGThing):
- """
- A class for generating the JITInfo for a property that points to
- our specialized getter and setter.
- """
- def __init__(self, descriptor, member):
- self.member = member
- self.descriptor = descriptor
-
- def declare(self):
- return ""
-
- def defineJitInfo(self, infoName, opName, infallible):
- protoID = "prototypes::id::%s" % self.descriptor.name
- depth = "PrototypeTraits<%s>::Depth" % protoID
- failstr = "true" if infallible else "false"
- return ("\n"
- "const JSJitInfo %s = {\n"
- " %s,\n"
- " %s,\n"
- " %s,\n"
- " %s, /* isInfallible. False in setters. */\n"
- " false /* isConstant. Only relevant for getters. */\n"
- "};\n" % (infoName, opName, protoID, depth, failstr))
-
- def define(self):
- if self.member.isAttr():
- getterinfo = ("%s_getterinfo" % self.member.identifier.name)
- getter = ("(JSJitPropertyOp)get_%s" % self.member.identifier.name)
- getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
- getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
- result = self.defineJitInfo(getterinfo, getter, getterinfal)
- if not self.member.readonly:
- setterinfo = ("%s_setterinfo" % self.member.identifier.name)
- setter = ("(JSJitPropertyOp)set_%s" % self.member.identifier.name)
- # Setters are always fallible, since they have to do a typed unwrap.
- result += self.defineJitInfo(setterinfo, setter, False)
- return result
- if self.member.isMethod():
- methodinfo = ("%s_methodinfo" % self.member.identifier.name)
- # Actually a JSJitMethodOp, but JSJitPropertyOp by struct definition.
- method = ("(JSJitPropertyOp)%s" % self.member.identifier.name)
-
- # Methods are infallible if they are infallible, have no arguments
- # to unwrap, and have a return type that's infallible to wrap up for
- # return.
- methodInfal = False
- sigs = self.member.signatures()
- if len(sigs) == 1:
- # Don't handle overloading. If there's more than one signature,
- # one of them must take arguments.
- sig = sigs[0]
- if len(sig[1]) == 0 and infallibleForMember(self.member, sig[0], self.descriptor):
- # No arguments and infallible return boxing
- methodInfal = True
-
- result = self.defineJitInfo(methodinfo, method, methodInfal)
- return result
- raise TypeError("Illegal member type to CGPropertyJITInfo")
-
-def getEnumValueName(value):
- # Some enum values can be empty strings. Others might have weird
- # characters in them. Deal with the former by returning "_empty",
- # deal with possible name collisions from that by throwing if the
- # enum value is actually "_empty", and throw on any value
- # containing chars other than [a-z] or '-' for now. Replace '-' with '_'.
- value = value.replace('-', '_')
- if value == "_empty":
- raise SyntaxError('"_empty" is not an IDL enum value we support yet')
- if value == "":
- return "_empty"
- if not re.match("^[a-z_]+$", value):
- raise SyntaxError('Enum value "' + value + '" contains characters '
- 'outside [a-z_]')
- return MakeNativeName(value)
-
-class CGEnum(CGThing):
- def __init__(self, enum):
- CGThing.__init__(self)
- self.enum = enum
-
- def declare(self):
- return """
- enum valuelist {
- %s
- };
-
- extern const EnumEntry strings[%d];
-""" % (",\n ".join(map(getEnumValueName, self.enum.values())),
- len(self.enum.values()) + 1)
-
- def define(self):
- return """
- const EnumEntry strings[%d] = {
- %s,
- { NULL, 0 }
- };
-""" % (len(self.enum.values()) + 1,
- ",\n ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()]))
-
-def getUnionAccessorSignatureType(type, descriptorProvider):
- """
- Returns the types that are used in the getter and setter signatures for
- union types
- """
- if type.isArray():
- raise TypeError("Can't handle array arguments yet")
-
- if type.isSequence():
- nullable = type.nullable();
- if nullable:
- type = type.inner.inner
- else:
- type = type.inner
- (elementTemplate, elementDeclType,
- elementHolderType, dealWithOptional) = getJSToNativeConversionTemplate(
- type, descriptorProvider, isSequenceMember=True)
- typeName = CGWrapper(elementDeclType, pre="Sequence< ", post=" >&")
- if nullable:
- typeName = CGWrapper(typeName, pre="Nullable< ", post=" >&")
-
- return typeName
-
- if type.isUnion():
- typeName = CGGeneric(type.name)
- if type.nullable():
- typeName = CGWrapper(typeName, pre="Nullable< ", post=" >&")
-
- return typeName
-
- if type.isGeckoInterface():
- descriptor = descriptorProvider.getDescriptor(
- type.unroll().inner.identifier.name)
- typeName = CGGeneric(descriptor.nativeType)
- # Allow null pointers for nullable types and old-binding classes
- if type.nullable() or type.unroll().inner.isExternal():
- typeName = CGWrapper(typeName, post="*")
- else:
- typeName = CGWrapper(typeName, post="&")
- return typeName
-
- if type.isSpiderMonkeyInterface():
- typeName = CGGeneric(type.name)
- if type.nullable():
- typeName = CGWrapper(typeName, post="*")
- else:
- typeName = CGWrapper(typeName, post="&")
- return typeName
-
- if type.isString():
- return CGGeneric("const nsAString&")
-
- if type.isEnum():
- if type.nullable():
- raise TypeError("We don't support nullable enumerated arguments or "
- "union members yet")
- return CGGeneric(type.inner.identifier.name)
-
- if type.isCallback():
- return CGGeneric("JSObject*")
-
- if type.isAny():
- return CGGeneric("JS::Value")
-
- if type.isObject():
- typeName = CGGeneric("JSObject")
- if type.nullable():
- typeName = CGWrapper(typeName, post="*")
- else:
- typeName = CGWrapper(typeName, post="&")
- return typeName
-
- if not type.isPrimitive():
- raise TypeError("Need native type for argument type '%s'" % str(type))
-
- typeName = CGGeneric(builtinNames[type.tag()])
- if type.nullable():
- typeName = CGWrapper(typeName, pre="Nullable< ", post=" >&")
- return typeName
-
-def getUnionTypeTemplateVars(type, descriptorProvider):
- # For dictionaries and sequences we need to pass None as the failureCode
- # for getJSToNativeConversionTemplate.
- # Also, for dictionaries we would need to handle conversion of
- # null/undefined to the dictionary correctly.
- if type.isDictionary() or type.isSequence():
- raise TypeError("Can't handle dictionaries or sequences in unions")
-
- if type.isGeckoInterface():
- name = type.inner.identifier.name
- elif type.isEnum():
- name = type.inner.identifier.name
- elif type.isArray() or type.isSequence():
- name = str(type)
- else:
- name = type.name
-
- tryNextCode = """tryNext = true;
-return true;"""
- if type.isGeckoInterface():
- tryNextCode = ("""if (mUnion.mType != mUnion.eUninitialized) {
- mUnion.Destroy%s();
-}""" % name) + tryNextCode
- (template, declType, holderType,
- dealWithOptional) = getJSToNativeConversionTemplate(
- type, descriptorProvider, failureCode=tryNextCode,
- isDefinitelyObject=True)
-
- # This is ugly, but UnionMember needs to call a constructor with no
- # arguments so the type can't be const.
- structType = declType.define()
- if structType.startswith("const "):
- structType = structType[6:]
- externalType = getUnionAccessorSignatureType(type, descriptorProvider).define()
-
- if type.isObject():
- setter = CGGeneric("void SetToObject(JSObject* obj)\n"
- "{\n"
- " mUnion.mValue.mObject.SetValue() = obj;\n"
- " mUnion.mType = mUnion.eObject;\n"
- "}")
- else:
- jsConversion = string.Template(template).substitute(
- {
- "val": "value",
- "valPtr": "pvalue",
- "declName": "SetAs" + name + "()",
- "holderName": "m" + name + "Holder"
- }
- )
- jsConversion = CGWrapper(CGGeneric(jsConversion),
- post="\n"
- "return true;")
- setter = CGWrapper(CGIndenter(jsConversion),
- pre="bool TrySetTo" + name + "(JSContext* cx, const JS::Value& value, JS::Value* pvalue, bool& tryNext)\n"
- "{\n"
- " tryNext = false;\n",
- post="\n"
- "}")
-
- return {
- "name": name,
- "structType": structType,
- "externalType": externalType,
- "setter": CGIndenter(setter).define(),
- "holderType": holderType.define() if holderType else None
- }
-
-def mapTemplate(template, templateVarArray):
- return map(lambda v: string.Template(template).substitute(v),
- templateVarArray)
-
-class CGUnionStruct(CGThing):
- def __init__(self, type, descriptorProvider):
- CGThing.__init__(self)
- self.type = type.unroll()
- self.descriptorProvider = descriptorProvider
-
- def declare(self):
- templateVars = map(lambda t: getUnionTypeTemplateVars(t, self.descriptorProvider),
- self.type.flatMemberTypes)
-
- callDestructors = []
- enumValues = []
- methods = []
- if self.type.hasNullableType:
- callDestructors.append(" case eNull:\n"
- " break;")
- enumValues.append("eNull")
- methods.append(""" bool IsNull() const
- {
- return mType == eNull;
- }""")
-
- destructorTemplate = """ void Destroy${name}()
- {
- MOZ_ASSERT(Is${name}(), "Wrong type!");
- mValue.m${name}.Destroy();
- mType = eUninitialized;
- }"""
- destructors = mapTemplate(destructorTemplate, templateVars)
- callDestructors.extend(mapTemplate(" case e${name}:\n"
- " Destroy${name}();\n"
- " break;", templateVars))
- enumValues.extend(mapTemplate("e${name}", templateVars))
- methodTemplate = """ bool Is${name}() const
- {
- return mType == e${name};
- }
- ${externalType} GetAs${name}() const
- {
- MOZ_ASSERT(Is${name}(), "Wrong type!");
- // The cast to ${externalType} is needed to work around a bug in Apple's
- // clang compiler, for some reason it doesn't call |S::operator T&| when
- // casting S<T> to T& and T is forward declared.
- return (${externalType})mValue.m${name}.Value();
- }
- ${structType}& SetAs${name}()
- {
- mType = e${name};
- return mValue.m${name}.SetValue();
- }"""
- methods.extend(mapTemplate(methodTemplate, templateVars))
- values = mapTemplate("UnionMember<${structType} > m${name};", templateVars)
- return string.Template("""
-class ${structName} {
-public:
- ${structName}() : mType(eUninitialized)
- {
- }
- ~${structName}()
- {
- switch (mType) {
-${callDestructors}
- case eUninitialized:
- break;
- }
- }
-
-${methods}
-
-private:
- friend class ${structName}Argument;
-
-${destructors}
-
- enum Type {
- eUninitialized,
- ${enumValues}
- };
- union Value {
- ${values}
- };
-
- Type mType;
- Value mValue;
-};
-
-""").substitute(
- {
- "structName": self.type.__str__(),
- "callDestructors": "\n".join(callDestructors),
- "destructors": "\n".join(destructors),
- "methods": "\n\n".join(methods),
- "enumValues": ",\n ".join(enumValues),
- "values": "\n ".join(values),
- })
-
- def define(self):
- return """
-"""
-
-class CGUnionConversionStruct(CGThing):
- def __init__(self, type, descriptorProvider):
- CGThing.__init__(self)
- self.type = type.unroll()
- self.descriptorProvider = descriptorProvider
-
- def declare(self):
- setters = []
-
- if self.type.hasNullableType:
- setters.append(""" bool SetNull()
- {
- mUnion.mType = mUnion.eNull;
- return true;
- }""")
-
- templateVars = map(lambda t: getUnionTypeTemplateVars(t, self.descriptorProvider),
- self.type.flatMemberTypes)
- structName = self.type.__str__()
-
- setters.extend(mapTemplate("${setter}", templateVars))
- private = "\n".join(mapTemplate(""" ${structType}& SetAs${name}()
- {
- mUnion.mType = mUnion.e${name};
- return mUnion.mValue.m${name}.SetValue();
- }""", templateVars))
- private += "\n\n"
- holders = filter(lambda v: v["holderType"] is not None, templateVars)
- if len(holders) > 0:
- private += "\n".join(mapTemplate(" ${holderType} m${name}Holder;", holders))
- private += "\n\n"
- private += " " + structName + "& mUnion;"
- return string.Template("""
-class ${structName}Argument {
-public:
- ${structName}Argument(const ${structName}& aUnion) : mUnion(const_cast<${structName}&>(aUnion))
- {
- }
-
-${setters}
-
-private:
-${private}
-};
-""").substitute({"structName": structName,
- "setters": "\n\n".join(setters),
- "private": private
- })
-
- def define(self):
- return """
-"""
-
-class ClassItem:
- """ Use with CGClass """
- def __init__(self, name, visibility):
- self.name = name
- self.visibility = visibility
- def declare(self, cgClass):
- assert False
- def define(self, cgClass):
- assert False
-
-class ClassBase(ClassItem):
- def __init__(self, name, visibility='public'):
- ClassItem.__init__(self, name, visibility)
- def declare(self, cgClass):
- return '%s %s' % (self.visibility, self.name)
- def define(self, cgClass):
- # Only in the header
- return ''
-
-class ClassMethod(ClassItem):
- def __init__(self, name, returnType, args, inline=False, static=False,
- virtual=False, const=False, bodyInHeader=False,
- templateArgs=None, visibility='public', body=None):
- self.returnType = returnType
- self.args = args
- self.inline = inline or bodyInHeader
- self.static = static
- self.virtual = virtual
- self.const = const
- self.bodyInHeader = bodyInHeader
- self.templateArgs = templateArgs
- self.body = body
- ClassItem.__init__(self, name, visibility)
-
- def getDecorators(self, declaring):
- decorators = []
- if self.inline:
- decorators.append('inline')
- if declaring:
- if self.static:
- decorators.append('static')
- if self.virtual:
- decorators.append('virtual')
- if decorators:
- return ' '.join(decorators) + ' '
- return ''
-
- def getBody(self):
- # Override me or pass a string to constructor
- assert self.body is not None
- return self.body
-
- def declare(self, cgClass):
- templateClause = 'template <%s>\n' % ', '.join(self.templateArgs) \
- if self.bodyInHeader and self.templateArgs else ''
- args = ', '.join([str(a) for a in self.args])
- if self.bodyInHeader:
- body = CGIndenter(CGGeneric(self.getBody())).define()
- body = '\n{\n' + body + '\n}'
- else:
- body = ';'
-
- return string.Template("""${templateClause}${decorators}${returnType}
-${name}(${args})${const}${body}
-""").substitute({ 'templateClause': templateClause,
- 'decorators': self.getDecorators(True),
- 'returnType': self.returnType,
- 'name': self.name,
- 'const': ' const' if self.const else '',
- 'args': args,
- 'body': body })
-
- def define(self, cgClass):
- if self.bodyInHeader:
- return ''
-
- templateArgs = cgClass.templateArgs
- if templateArgs:
- if cgClass.templateSpecialization:
- templateArgs = \
- templateArgs[len(cgClass.templateSpecialization):]
-
- if templateArgs:
- templateClause = \
- 'template <%s>\n' % ', '.join([str(a) for a in templateArgs])
- else:
- templateClause = ''
-
- args = ', '.join([str(a) for a in self.args])
-
- body = CGIndenter(CGGeneric(self.getBody())).define()
-
- return string.Template("""${templateClause}${decorators}${returnType}
-${className}::${name}(${args})${const}
-{
-${body}
-}\n
-""").substitute({ 'templateClause': templateClause,
- 'decorators': self.getDecorators(False),
- 'returnType': self.returnType,
- 'className': cgClass.getNameString(),
- 'name': self.name,
- 'args': args,
- 'const': ' const' if self.const else '',
- 'body': body })
-
-class ClassConstructor(ClassItem):
- """
- Used for adding a constructor to a CGClass.
-
- args is a list of Argument objects that are the arguments taken by the
- constructor.
-
- inline should be True if the constructor should be marked inline.
-
- bodyInHeader should be True if the body should be placed in the class
- declaration in the header.
-
- visibility determines the visibility of the constructor (public,
- protected, private), defaults to private.
-
- baseConstructors is a list of strings containing calls to base constructors,
- defaults to None.
-
- body contains a string with the code for the constructor, defaults to None.
- """
- def __init__(self, args, inline=False, bodyInHeader=False,
- visibility="private", baseConstructors=None, body=None):
- self.args = args
- self.inline = inline or bodyInHeader
- self.bodyInHeader = bodyInHeader
- self.baseConstructors = baseConstructors
- self.body = body
- ClassItem.__init__(self, None, visibility)
-
- def getDecorators(self, declaring):
- decorators = []
- if self.inline and declaring:
- decorators.append('inline')
- if decorators:
- return ' '.join(decorators) + ' '
- return ''
-
- def getInitializationList(self, cgClass):
- items = [str(c) for c in self.baseConstructors]
- for m in cgClass.members:
- if not m.static:
- initialize = m.getBody()
- if initialize:
- items.append(m.name + "(" + initialize + ")")
-
- if len(items) > 0:
- return '\n : ' + ',\n '.join(items)
- return ''
-
- def getBody(self):
- assert self.body is not None
- return self.body
-
- def declare(self, cgClass):
- args = ', '.join([str(a) for a in self.args])
- if self.bodyInHeader:
- body = ' ' + self.getBody();
- body = stripTrailingWhitespace(body.replace('\n', '\n '))
- if len(body) > 0:
- body += '\n'
- body = self.getInitializationList(cgClass) + '\n{\n' + body + '}'
- else:
- body = ';'
-
- return string.Template("""${decorators}${className}(${args})${body}
-""").substitute({ 'decorators': self.getDecorators(True),
- 'className': cgClass.getNameString(),
- 'args': args,
- 'body': body })
-
- def define(self, cgClass):
- if self.bodyInHeader:
- return ''
-
- args = ', '.join([str(a) for a in self.args])
-
- body = ' ' + self.getBody()
- body = '\n' + stripTrailingWhitespace(body.replace('\n', '\n '))
- if len(body) > 0:
- body += '\n'
-
- return string.Template("""${decorators}
-${className}::${className}(${args})${initializationList}
-{${body}}\n
-""").substitute({ 'decorators': self.getDecorators(False),
- 'className': cgClass.getNameString(),
- 'args': args,
- 'initializationList': self.getInitializationList(cgClass),
- 'body': body })
-
-class ClassMember(ClassItem):
- def __init__(self, name, type, visibility="private", static=False,
- body=None):
- self.type = type;
- self.static = static
- self.body = body
- ClassItem.__init__(self, name, visibility)
-
- def declare(self, cgClass):
- return '%s%s %s;\n' % ('static ' if self.static else '', self.type,
- self.name)
-
- def define(self, cgClass):
- if not self.static:
- return ''
- if self.body:
- body = " = " + self.body
- else:
- body = ""
- return '%s %s::%s%s;\n' % (self.type, cgClass.getNameString(),
- self.name, body)
-
-class ClassTypedef(ClassItem):
- def __init__(self, name, type, visibility="public"):
- self.type = type
- ClassItem.__init__(self, name, visibility)
-
- def declare(self, cgClass):
- return 'typedef %s %s;\n' % (self.type, self.name)
-
- def define(self, cgClass):
- # Only goes in the header
- return ''
-
-class ClassEnum(ClassItem):
- def __init__(self, name, entries, values=None, visibility="public"):
- self.entries = entries
- self.values = values
- ClassItem.__init__(self, name, visibility)
-
- def declare(self, cgClass):
- entries = []
- for i in range(0, len(self.entries)):
- if i >= len(self.values):
- entry = '%s' % self.entries[i]
- else:
- entry = '%s = %s' % (self.entries[i], self.values[i])
- entries.append(entry)
- name = '' if not self.name else ' ' + self.name
- return 'enum%s\n{\n %s\n};\n' % (name, ',\n '.join(entries))
-
- def define(self, cgClass):
- # Only goes in the header
- return ''
-
-class CGClass(CGThing):
- def __init__(self, name, bases=[], members=[], constructors=[], methods=[],
- typedefs = [], enums=[], templateArgs=[],
- templateSpecialization=[], isStruct=False, indent=''):
- CGThing.__init__(self)
- self.name = name
- self.bases = bases
- self.members = members
- self.constructors = constructors
- self.methods = methods
- self.typedefs = typedefs
- self.enums = enums
- self.templateArgs = templateArgs
- self.templateSpecialization = templateSpecialization
- self.isStruct = isStruct
- self.indent = indent
- self.defaultVisibility ='public' if isStruct else 'private'
-
- def getNameString(self):
- className = self.name
- if self.templateSpecialization:
- className = className + \
- '<%s>' % ', '.join([str(a) for a
- in self.templateSpecialization])
- return className
-
- def declare(self):
- result = ''
- if self.templateArgs:
- templateArgs = [str(a) for a in self.templateArgs]
- templateArgs = templateArgs[len(self.templateSpecialization):]
- result = result + self.indent + 'template <%s>\n' \
- % ','.join([str(a) for a in templateArgs])
-
- type = 'struct' if self.isStruct else 'class'
-
- if self.templateSpecialization:
- specialization = \
- '<%s>' % ', '.join([str(a) for a in self.templateSpecialization])
- else:
- specialization = ''
-
- result = result + '%s%s %s%s' \
- % (self.indent, type, self.name, specialization)
-
- if self.bases:
- result = result + ' : %s' % ', '.join([d.declare(self) for d in self.bases])
-
- result = result + '\n%s{\n' % self.indent
-
- def declareMembers(cgClass, memberList, defaultVisibility, itemCount,
- separator=''):
- members = { 'private': [], 'protected': [], 'public': [] }
-
- for member in memberList:
- members[member.visibility].append(member)
-
-
- if defaultVisibility == 'public':
- order = [ 'public', 'protected', 'private' ]
- else:
- order = [ 'private', 'protected', 'public' ]
-
- result = ''
-
- lastVisibility = defaultVisibility
- for visibility in order:
- list = members[visibility]
- if list:
- if visibility != lastVisibility:
- if itemCount:
- result = result + '\n'
- result = result + visibility + ':\n'
- itemCount = 0
- for member in list:
- if itemCount != 0:
- result = result + separator
- declaration = member.declare(cgClass)
- declaration = CGIndenter(CGGeneric(declaration)).define()
- result = result + declaration
- itemCount = itemCount + 1
- lastVisibility = visibility
- return (result, lastVisibility, itemCount)
-
- order = [(self.enums, ''), (self.typedefs, ''), (self.members, ''),
- (self.constructors, '\n'), (self.methods, '\n')]
-
- lastVisibility = self.defaultVisibility
- itemCount = 0
- for (memberList, separator) in order:
- (memberString, lastVisibility, itemCount) = \
- declareMembers(self, memberList, lastVisibility, itemCount,
- separator)
- if self.indent:
- memberString = CGIndenter(CGGeneric(memberString),
- len(self.indent)).define()
- result = result + memberString
-
- result = result + self.indent + '};\n'
- return result
-
- def define(self):
- def defineMembers(cgClass, memberList, itemCount, separator=''):
- result = ''
- for member in memberList:
- if itemCount != 0:
- result = result + separator
- result = result + member.define(cgClass)
- itemCount = itemCount + 1
- return (result, itemCount)
-
- order = [(self.members, '\n'), (self.constructors, '\n'),
- (self.methods, '\n')]
-
- result = ''
- itemCount = 0
- for (memberList, separator) in order:
- (memberString, itemCount) = defineMembers(self, memberList,
- itemCount, separator)
- result = result + memberString
- return result
-
-class CGResolveOwnProperty(CGAbstractMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
- Argument('jsid', 'id'), Argument('bool', 'set'),
- Argument('JSPropertyDescriptor*', 'desc')]
- CGAbstractMethod.__init__(self, descriptor, "ResolveOwnProperty", "bool", args)
- def definition_body(self):
- return """ JSObject* obj = wrapper;
- if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
- obj = js::UnwrapObject(obj);
- }
- // We rely on getOwnPropertyDescriptor not shadowing prototype properties by named
- // properties. If that changes we'll need to filter here.
- return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, set, desc);
-"""
-
-class CGEnumerateOwnProperties(CGAbstractMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
- Argument('JS::AutoIdVector&', 'props')]
- CGAbstractMethod.__init__(self, descriptor, "EnumerateOwnProperties", "bool", args)
- def definition_body(self):
- return """ JSObject* obj = wrapper;
- if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
- obj = js::UnwrapObject(obj);
- }
- // We rely on getOwnPropertyNames not shadowing prototype properties by named
- // properties. If that changes we'll need to filter here.
- return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
-"""
-
-class CGXrayHelper(CGAbstractMethod):
- def __init__(self, descriptor, name, args, properties):
- CGAbstractMethod.__init__(self, descriptor, name, "bool", args)
- self.properties = properties
-
- def definition_body(self):
- varNames = self.properties.variableNames(True)
-
- methods = self.properties.methods
- if methods.hasNonChromeOnly() or methods.hasChromeOnly():
- methodArgs = """// %(methods)s has an end-of-list marker at the end that we ignore
-%(methods)s, %(methods)s_ids, %(methods)s_specs, ArrayLength(%(methods)s) - 1""" % varNames
- else:
- methodArgs = "NULL, NULL, NULL, 0"
- methodArgs = CGGeneric(methodArgs)
-
- attrs = self.properties.attrs
- if attrs.hasNonChromeOnly() or attrs.hasChromeOnly():
- attrArgs = """// %(attrs)s has an end-of-list marker at the end that we ignore
-%(attrs)s, %(attrs)s_ids, %(attrs)s_specs, ArrayLength(%(attrs)s) - 1""" % varNames
- else:
- attrArgs = "NULL, NULL, NULL, 0"
- attrArgs = CGGeneric(attrArgs)
-
- consts = self.properties.consts
- if consts.hasNonChromeOnly() or consts.hasChromeOnly():
- constArgs = """// %(consts)s has an end-of-list marker at the end that we ignore
-%(consts)s, %(consts)s_ids, %(consts)s_specs, ArrayLength(%(consts)s) - 1""" % varNames
- else:
- constArgs = "NULL, NULL, NULL, 0"
- constArgs = CGGeneric(constArgs)
-
- prefixArgs = CGGeneric(self.getPrefixArgs())
-
- return CGIndenter(
- CGWrapper(CGList([prefixArgs, methodArgs, attrArgs, constArgs], ",\n"),
- pre=("return Xray%s(" % self.name),
- post=");",
- reindent=True)).define()
-
-class CGResolveProperty(CGXrayHelper):
- def __init__(self, descriptor, properties):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
- Argument('jsid', 'id'), Argument('bool', 'set'),
- Argument('JSPropertyDescriptor*', 'desc')]
- CGXrayHelper.__init__(self, descriptor, "ResolveProperty", args,
- properties)
-
- def getPrefixArgs(self):
- return "cx, wrapper, id, desc"
-
-
-class CGEnumerateProperties(CGXrayHelper):
- def __init__(self, descriptor, properties):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'wrapper'),
- Argument('JS::AutoIdVector&', 'props')]
- CGXrayHelper.__init__(self, descriptor, "EnumerateProperties", args,
- properties)
-
- def getPrefixArgs(self):
- return "props"
-
-class CGPrototypeTraitsClass(CGClass):
- def __init__(self, descriptor, indent=''):
- templateArgs = [Argument('prototypes::ID', 'PrototypeID')]
- templateSpecialization = ['prototypes::id::' + descriptor.name]
- enums = [ClassEnum('', ['Depth'],
- [descriptor.interface.inheritanceDepth()])]
- typedefs = [ClassTypedef('NativeType', descriptor.nativeType)]
- CGClass.__init__(self, 'PrototypeTraits', indent=indent,
- templateArgs=templateArgs,
- templateSpecialization=templateSpecialization,
- enums=enums, typedefs=typedefs, isStruct=True)
-
-class CGPrototypeIDMapClass(CGClass):
- def __init__(self, descriptor, indent=''):
- templateArgs = [Argument('class', 'ConcreteClass')]
- templateSpecialization = [descriptor.nativeType]
- enums = [ClassEnum('', ['PrototypeID'],
- ['prototypes::id::' + descriptor.name])]
- CGClass.__init__(self, 'PrototypeIDMap', indent=indent,
- templateArgs=templateArgs,
- templateSpecialization=templateSpecialization,
- enums=enums, isStruct=True)
-
-class CGClassForwardDeclare(CGThing):
- def __init__(self, name, isStruct=False):
- CGThing.__init__(self)
- self.name = name
- self.isStruct = isStruct
- def declare(self):
- type = 'struct' if self.isStruct else 'class'
- return '%s %s;\n' % (type, self.name)
- def define(self):
- # Header only
- return ''
-
-class CGProxySpecialOperation(CGPerSignatureCall):
- """
- Base class for classes for calling an indexed or named special operation
- (don't use this directly, use the derived classes below).
- """
- def __init__(self, descriptor, operation):
- nativeName = MakeNativeName(descriptor.binaryNames.get(operation, operation))
- operation = descriptor.operations[operation]
- assert len(operation.signatures()) == 1
- signature = operation.signatures()[0]
- extendedAttributes = descriptor.getExtendedAttributes(operation)
-
- (returnType, arguments) = signature
-
- # We pass len(arguments) as the final argument so that the
- # CGPerSignatureCall won't do any argument conversion of its own.
- CGPerSignatureCall.__init__(self, returnType, "", arguments, nativeName,
- False, descriptor, operation,
- len(arguments))
-
- if operation.isSetter() or operation.isCreator():
- # arguments[0] is the index or name of the item that we're setting.
- argument = arguments[1]
- template = getJSToNativeConversionTemplate(argument.type, descriptor,
- treatNullAs=argument.treatNullAs,
- treatUndefinedAs=argument.treatUndefinedAs)
- templateValues = {
- "declName": argument.identifier.name,
- "holderName": argument.identifier.name + "_holder",
- "val": "desc->value",
- "valPtr": "&desc->value"
- }
- self.cgRoot.prepend(instantiateJSToNativeConversionTemplate(template, templateValues))
- elif operation.isGetter():
- self.cgRoot.prepend(CGGeneric("bool found;"))
-
- def getArguments(self):
- args = [(a, a.identifier.name) for a in self.arguments]
- if self.idlNode.isGetter():
- args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean],
- self.idlNode),
- "found"))
- return args
-
- def wrap_return_value(self):
- if not self.idlNode.isGetter() or self.templateValues is None:
- return ""
-
- wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues))
- wrap = CGIfWrapper(wrap, "found")
- return "\n" + wrap.define()
-
-class CGProxyIndexedGetter(CGProxySpecialOperation):
- """
- Class to generate a call to an indexed getter. If templateValues is not None
- the returned value will be wrapped with wrapForType using templateValues.
- """
- def __init__(self, descriptor, templateValues=None):
- self.templateValues = templateValues
- CGProxySpecialOperation.__init__(self, descriptor, 'IndexedGetter')
-
-class CGProxyIndexedSetter(CGProxySpecialOperation):
- """
- Class to generate a call to an indexed setter.
- """
- def __init__(self, descriptor):
- CGProxySpecialOperation.__init__(self, descriptor, 'IndexedSetter')
-
-class CGProxyNamedGetter(CGProxySpecialOperation):
- """
- Class to generate a call to an named getter. If templateValues is not None
- the returned value will be wrapped with wrapForType using templateValues.
- """
- def __init__(self, descriptor, templateValues=None):
- self.templateValues = templateValues
- CGProxySpecialOperation.__init__(self, descriptor, 'NamedGetter')
-
-class CGProxyNamedSetter(CGProxySpecialOperation):
- """
- Class to generate a call to a named setter.
- """
- def __init__(self, descriptor):
- CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter')
-
-class CGProxyIsProxy(CGAbstractMethod):
- def __init__(self, descriptor):
- args = [Argument('JSObject*', 'obj')]
- CGAbstractMethod.__init__(self, descriptor, "IsProxy", "bool", args, alwaysInline=True)
- def declare(self):
- return ""
- def definition_body(self):
- return " return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();"
-
-class CGProxyUnwrap(CGAbstractMethod):
- def __init__(self, descriptor):
- args = [Argument('JSObject*', 'obj')]
- CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", descriptor.nativeType + '*', args, alwaysInline=True)
- def declare(self):
- return ""
- def definition_body(self):
- return """ if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
- obj = js::UnwrapObject(obj);
- }
- MOZ_ASSERT(IsProxy(obj));
- return static_cast<%s*>(js::GetProxyPrivate(obj).toPrivate());""" % (self.descriptor.nativeType)
-
-class CGDOMJSProxyHandlerDOMClass(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
- def declare(self):
- return "extern const DOMClass Class;\n"
- def define(self):
- return """
-const DOMClass Class = """ + DOMClass(self.descriptor) + """;
-
-"""
-
-class CGDOMJSProxyHandler_CGDOMJSProxyHandler(ClassConstructor):
- def __init__(self):
- ClassConstructor.__init__(self, [], inline=True, visibility="private",
- baseConstructors=["mozilla::dom::DOMProxyHandler(Class)"],
- body="")
-
-class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
- Argument('jsid', 'id'), Argument('bool', 'set'),
- Argument('JSPropertyDescriptor*', 'desc')]
- ClassMethod.__init__(self, "getOwnPropertyDescriptor", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- indexedGetter = self.descriptor.operations['IndexedGetter']
- indexedSetter = self.descriptor.operations['IndexedSetter']
-
- setOrIndexedGet = ""
- if indexedGetter or indexedSetter:
- setOrIndexedGet += "int32_t index = GetArrayIndexFromId(cx, id);\n"
-
- if indexedGetter:
- readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
- fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
- templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
- 'obj': 'proxy', 'successCode': fillDescriptor}
- get = ("if (index >= 0) {\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" +
- "}\n") % (self.descriptor.nativeType)
-
- if indexedSetter or self.descriptor.operations['NamedSetter']:
- setOrIndexedGet += "if (set) {\n"
- if indexedSetter:
- setOrIndexedGet += (" if (index >= 0) {\n")
- if not 'IndexedCreator' in self.descriptor.operations:
- # FIXME need to check that this is a 'supported property index'
- assert False
- setOrIndexedGet += (" FillPropertyDescriptor(desc, proxy, JSVAL_VOID, false);\n" +
- " return true;\n" +
- " }\n")
- if self.descriptor.operations['NamedSetter']:
- setOrIndexedGet += " if (JSID_IS_STRING(id)) {\n"
- if not 'NamedCreator' in self.descriptor.operations:
- # FIXME need to check that this is a 'supported property name'
- assert False
- setOrIndexedGet += (" FillPropertyDescriptor(desc, proxy, JSVAL_VOID, false);\n" +
- " return true;\n" +
- " }\n")
- setOrIndexedGet += "}"
- if indexedGetter:
- setOrIndexedGet += (" else {\n" +
- CGIndenter(CGGeneric(get)).define() +
- "}")
- setOrIndexedGet += "\n\n"
- elif indexedGetter:
- setOrIndexedGet += ("if (!set) {\n" +
- CGIndenter(CGGeneric(get)).define() +
- "}\n\n")
-
- namedGetter = self.descriptor.operations['NamedGetter']
- if namedGetter:
- readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
- fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
- templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
- 'obj': 'proxy', 'successCode': fillDescriptor}
- # Once we start supporting OverrideBuiltins we need to make
- # ResolveOwnProperty or EnumerateOwnProperties filter out named
- # properties that shadow prototype properties.
- namedGet = ("\n" +
- "if (!set && JSID_IS_STRING(id) && !HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
- " JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
- " FakeDependentString name;\n"
- " if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
- " eStringify, eStringify, name)) {\n" +
- " return false;\n" +
- " }\n" +
- "\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" +
- "}\n") % (self.descriptor.nativeType)
- else:
- namedGet = ""
-
- return setOrIndexedGet + """JSObject* expando;
-if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
- unsigned flags = (set ? JSRESOLVE_ASSIGNING : 0) | JSRESOLVE_QUALIFIED;
- if (!JS_GetPropertyDescriptorById(cx, expando, id, flags, desc)) {
- return false;
- }
- if (desc->obj) {
- // Pretend the property lives on the wrapper.
- desc->obj = proxy;
- return true;
- }
-}
-""" + namedGet + """
-desc->obj = NULL;
-return true;"""
-
-class CGDOMJSProxyHandler_defineProperty(ClassMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
- Argument('jsid', 'id'),
- Argument('JSPropertyDescriptor*', 'desc')]
- ClassMethod.__init__(self, "defineProperty", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- set = ""
-
- indexedSetter = self.descriptor.operations['IndexedSetter']
- if indexedSetter:
- if not (self.descriptor.operations['IndexedCreator'] is indexedSetter):
- raise TypeError("Can't handle creator that's different from the setter")
- set += ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
- "if (index >= 0) {\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyIndexedSetter(self.descriptor)).define() +
- " return true;\n" +
- "}\n") % (self.descriptor.nativeType)
- elif self.descriptor.operations['IndexedGetter']:
- set += ("if (GetArrayIndexFromId(cx, id) >= 0) {\n" +
- " return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
- "}\n") % self.descriptor.name
-
- namedSetter = self.descriptor.operations['NamedSetter']
- if namedSetter:
- if not self.descriptor.operations['NamedCreator'] is namedSetter:
- raise TypeError("Can't handle creator that's different from the setter")
- set += ("if (JSID_IS_STRING(id)) {\n" +
- " JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
- " FakeDependentString name;\n"
- " if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
- " eStringify, eStringify, name)) {\n" +
- " return false;\n" +
- " }\n" +
- "\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyNamedSetter(self.descriptor)).define() + "\n" +
- "}\n") % (self.descriptor.nativeType)
- elif self.descriptor.operations['NamedGetter']:
- set += ("if (JSID_IS_STRING(id)) {\n" +
- " JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
- " FakeDependentString name;\n"
- " if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
- " eStringify, eStringify, name)) {\n" +
- " return false;\n" +
- " }\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyNamedGetter(self.descriptor)).define() +
- " if (found) {\n"
- " return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
- " }\n" +
- " return true;\n"
- "}\n") % (self.descriptor.nativeType, self.descriptor.name)
- return set + """return mozilla::dom::DOMProxyHandler::defineProperty(%s);""" % ", ".join(a.name for a in self.args)
-
-class CGDOMJSProxyHandler_getOwnPropertyNames(ClassMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
- Argument('JS::AutoIdVector&', 'props')]
- ClassMethod.__init__(self, "getOwnPropertyNames", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- indexedGetter = self.descriptor.operations['IndexedGetter']
- if indexedGetter:
- addIndices = """uint32_t length = UnwrapProxy(proxy)->Length();
-MOZ_ASSERT(int32_t(length) >= 0);
-for (int32_t i = 0; i < int32_t(length); ++i) {
- if (!props.append(INT_TO_JSID(i))) {
- return false;
- }
-}
-
-"""
- else:
- addIndices = ""
-
- return addIndices + """JSObject* expando;
-if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
- !js::GetPropertyNames(cx, expando, JSITER_OWNONLY | JSITER_HIDDEN, &props)) {
- return false;
-}
-
-// FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=772869 Add named items
-return true;"""
-
-class CGDOMJSProxyHandler_hasOwn(ClassMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
- Argument('jsid', 'id'), Argument('bool*', 'bp')]
- ClassMethod.__init__(self, "hasOwn", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- indexedGetter = self.descriptor.operations['IndexedGetter']
- if indexedGetter:
- indexed = ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
- "if (index >= 0) {\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" +
- " *bp = found;\n" +
- " return true;\n" +
- "}\n\n") % (self.descriptor.nativeType)
- else:
- indexed = ""
-
- namedGetter = self.descriptor.operations['NamedGetter']
- if namedGetter:
- named = ("if (JSID_IS_STRING(id) && !HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
- " jsval nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
- " FakeDependentString name;\n"
- " if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
- " eStringify, eStringify, name)) {\n" +
- " return false;\n" +
- " }\n" +
- "\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" +
- " *bp = found;\n"
- " return true;\n"
- "}\n" +
- "\n") % (self.descriptor.nativeType)
- else:
- named = ""
-
- return indexed + """JSObject* expando = GetExpandoObject(proxy);
-if (expando) {
- JSBool b = true;
- JSBool ok = JS_HasPropertyById(cx, expando, id, &b);
- *bp = !!b;
- if (!ok || *bp) {
- return ok;
- }
-}
-
-""" + named + """*bp = false;
-return true;"""
-
-class CGDOMJSProxyHandler_get(ClassMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
- Argument('JSObject*', 'receiver'), Argument('jsid', 'id'),
- Argument('JS::Value*', 'vp')]
- ClassMethod.__init__(self, "get", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- getFromExpando = """JSObject* expando = DOMProxyHandler::GetExpandoObject(proxy);
-if (expando) {
- JSBool hasProp;
- if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
- return false;
- }
-
- if (hasProp) {
- return JS_GetPropertyById(cx, expando, id, vp);
- }
-}"""
-
- templateValues = {'jsvalRef': '*vp', 'jsvalPtr': 'vp', 'obj': 'proxy'}
-
- indexedGetter = self.descriptor.operations['IndexedGetter']
- if indexedGetter:
- getIndexedOrExpando = ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
- "if (index >= 0) {\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define()) % (self.descriptor.nativeType)
- getIndexedOrExpando += """
- // Even if we don't have this index, we don't forward the
- // get on to our expando object.
-} else {
- %s
-}
-""" % (stripTrailingWhitespace(getFromExpando.replace('\n', '\n ')))
- else:
- getIndexedOrExpando = getFromExpando + "\n"
-
- namedGetter = self.descriptor.operations['NamedGetter']
- if namedGetter:
- getNamed = ("if (JSID_IS_STRING(id)) {\n" +
- " JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
- " FakeDependentString name;\n"
- " if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
- " eStringify, eStringify, name)) {\n" +
- " return false;\n" +
- " }\n" +
- "\n" +
- " %s* self = UnwrapProxy(proxy);\n" +
- CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() +
- "}\n") % (self.descriptor.nativeType)
- else:
- getNamed = ""
-
- return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
- "Should not have a XrayWrapper here");
-
-%s
-bool found;
-if (!GetPropertyOnPrototype(cx, proxy, id, &found, vp)) {
- return false;
-}
-
-if (found) {
- return true;
-}
-%s
-vp->setUndefined();
-return true;""" % (getIndexedOrExpando, getNamed)
-
-class CGDOMJSProxyHandler_obj_toString(ClassMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy')]
- ClassMethod.__init__(self, "obj_toString", "JSString*", args)
- self.descriptor = descriptor
- def getBody(self):
- stringifier = self.descriptor.operations['Stringifier']
- if stringifier:
- name = stringifier.identifier.name
- nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
- signature = stringifier.signatures()[0]
- returnType = signature[0]
- extendedAttributes = self.descriptor.getExtendedAttributes(stringifier)
- infallible = 'infallible' in extendedAttributes
- if not infallible:
- error = CGGeneric(
- ('ThrowMethodFailedWithDetails(cx, rv, "%s", "toString");\n' +
- "return NULL;") % self.descriptor.interface.identifier.name)
- else:
- error = None
- call = CGCallGenerator(error, [], "", returnType, extendedAttributes, self.descriptor, nativeName, False, object="UnwrapProxy(proxy)")
- return call.define() + """
-
-JSString* jsresult;
-return xpc_qsStringToJsstring(cx, result, &jsresult) ? jsresult : NULL;"""
-
- return "return mozilla::dom::DOMProxyHandler::obj_toString(cx, \"%s\");" % self.descriptor.name
-
-class CGDOMJSProxyHandler_finalize(ClassMethod):
- def __init__(self, descriptor):
- args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'proxy')]
- ClassMethod.__init__(self, "finalize", "void", args)
- self.descriptor = descriptor
- def getBody(self):
- return ("%s self = UnwrapProxy(proxy);\n\n" % (self.descriptor.nativeType + "*") +
- finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name))
-
-class CGDOMJSProxyHandler_getElementIfPresent(ClassMethod):
- def __init__(self, descriptor):
- args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
- Argument('JSObject*', 'receiver'),
- Argument('uint32_t', 'index'),
- Argument('JS::Value*', 'vp'), Argument('bool*', 'present')]
- ClassMethod.__init__(self, "getElementIfPresent", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- indexedGetter = self.descriptor.operations['IndexedGetter']
- if indexedGetter:
- successCode = """*present = found;
-return true;"""
- templateValues = {'jsvalRef': '*vp', 'jsvalPtr': 'vp',
- 'obj': 'proxy', 'successCode': successCode}
- get = ("%s* self = UnwrapProxy(proxy);\n" +
- CGProxyIndexedGetter(self.descriptor, templateValues).define() + "\n"
- "// We skip the expando object if there is an indexed getter.\n" +
- "\n") % (self.descriptor.nativeType)
- else:
- get = """
-
-JSObject* expando = GetExpandoObject(proxy);
-if (expando) {
- JSBool isPresent;
- if (!JS_GetElementIfPresent(cx, expando, index, expando, vp, &isPresent)) {
- return false;
- }
- if (isPresent) {
- *present = true;
- return true;
- }
-}
-"""
-
- return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
- "Should not have a XrayWrapper here");
-
-""" + get + """
-// No need to worry about name getters here, so just check the proto.
-
-JSObject *proto;
-if (!js::GetObjectProto(cx, proxy, &proto)) {
- return false;
-}
-if (proto) {
- JSBool isPresent;
- if (!JS_GetElementIfPresent(cx, proto, index, proxy, vp, &isPresent)) {
- return false;
- }
- *present = isPresent;
- return true;
-}
-
-*present = false;
-// Can't Debug_SetValueRangeToCrashOnTouch because it's not public
-return true;"""
-
-class CGDOMJSProxyHandler_getInstance(ClassMethod):
- def __init__(self):
- ClassMethod.__init__(self, "getInstance", "DOMProxyHandler*", [], static=True)
- def getBody(self):
- return """static DOMProxyHandler instance;
-return &instance;"""
-
-class CGDOMJSProxyHandler(CGClass):
- def __init__(self, descriptor):
- constructors = [CGDOMJSProxyHandler_CGDOMJSProxyHandler()]
- methods = [CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor)]
- if descriptor.operations['IndexedSetter'] or descriptor.operations['NamedSetter']:
- methods.append(CGDOMJSProxyHandler_defineProperty(descriptor))
- methods.extend([CGDOMJSProxyHandler_getOwnPropertyNames(descriptor),
- CGDOMJSProxyHandler_hasOwn(descriptor),
- CGDOMJSProxyHandler_get(descriptor),
- CGDOMJSProxyHandler_obj_toString(descriptor),
- CGDOMJSProxyHandler_finalize(descriptor),
- CGDOMJSProxyHandler_getElementIfPresent(descriptor),
- CGDOMJSProxyHandler_getInstance()])
- CGClass.__init__(self, 'DOMProxyHandler',
- bases=[ClassBase('mozilla::dom::DOMProxyHandler')],
- constructors=constructors,
- methods=methods)
-
-def stripTrailingWhitespace(text):
- tail = '\n' if text.endswith('\n') else ''
- lines = text.splitlines()
- for i in range(len(lines)):
- lines[i] = lines[i].rstrip()
- return '\n'.join(lines) + tail
-
-class CGDescriptor(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
-
- assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
-
- cgThings = []
- if descriptor.interface.hasInterfacePrototypeObject():
- (hasMethod, hasGetter, hasLenientGetter,
- hasSetter, hasLenientSetter) = False, False, False, False, False
- for m in descriptor.interface.members:
- if m.isMethod() and not m.isStatic() and not m.isIdentifierLess():
- cgThings.append(CGSpecializedMethod(descriptor, m))
- cgThings.append(CGMemberJITInfo(descriptor, m))
- hasMethod = True
- elif m.isAttr():
- cgThings.append(CGSpecializedGetter(descriptor, m))
- if m.hasLenientThis():
- hasLenientGetter = True
- else:
- hasGetter = True
- if not m.readonly:
- cgThings.append(CGSpecializedSetter(descriptor, m))
- if m.hasLenientThis():
- hasLenientSetter = True
- else:
- hasSetter = True
- cgThings.append(CGMemberJITInfo(descriptor, m))
- if hasMethod: cgThings.append(CGGenericMethod(descriptor))
- if hasGetter: cgThings.append(CGGenericGetter(descriptor))
- if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor,
- lenientThis=True))
- if hasSetter: cgThings.append(CGGenericSetter(descriptor))
- if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor,
- lenientThis=True))
-
- if descriptor.concrete and not descriptor.proxy:
- if not descriptor.workers and descriptor.wrapperCache:
- cgThings.append(CGAddPropertyHook(descriptor))
-
- # Always have a finalize hook, regardless of whether the class wants a
- # custom hook.
- cgThings.append(CGClassFinalizeHook(descriptor))
-
- # Only generate a trace hook if the class wants a custom hook.
- if (descriptor.customTrace):
- cgThings.append(CGClassTraceHook(descriptor))
-
- if descriptor.interface.hasInterfaceObject():
- cgThings.append(CGClassConstructHook(descriptor))
- cgThings.append(CGClassHasInstanceHook(descriptor))
- cgThings.append(CGInterfaceObjectJSClass(descriptor))
-
- if descriptor.interface.hasInterfacePrototypeObject():
- cgThings.append(CGPrototypeJSClass(descriptor))
-
- properties = PropertyArrays(descriptor)
- cgThings.append(CGGeneric(define=str(properties)))
- cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
- if descriptor.interface.hasInterfacePrototypeObject():
- cgThings.append(CGGetProtoObjectMethod(descriptor))
- else:
- cgThings.append(CGGetConstructorObjectMethod(descriptor))
-
- # Set up our Xray callbacks as needed. Note that we don't need to do
- # it in workers.
- if (descriptor.interface.hasInterfacePrototypeObject() and
- not descriptor.workers):
- if descriptor.concrete and descriptor.proxy:
- cgThings.append(CGResolveOwnProperty(descriptor))
- cgThings.append(CGEnumerateOwnProperties(descriptor))
- cgThings.append(CGResolveProperty(descriptor, properties))
- cgThings.append(CGEnumerateProperties(descriptor, properties))
-
- if descriptor.interface.hasInterfaceObject():
- cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
- if (not descriptor.interface.isExternal() and
- # Workers stuff is never pref-controlled
- not descriptor.workers and
- descriptor.interface.getExtendedAttribute("PrefControlled") is not None):
- cgThings.append(CGPrefEnabled(descriptor))
-
- if descriptor.interface.hasInterfacePrototypeObject():
- cgThings.append(CGNativePropertyHooks(descriptor))
-
- if descriptor.concrete:
- if descriptor.proxy:
- cgThings.append(CGProxyIsProxy(descriptor))
- cgThings.append(CGProxyUnwrap(descriptor))
- cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor))
- cgThings.append(CGDOMJSProxyHandler(descriptor))
- cgThings.append(CGIsMethod(descriptor))
- else:
- cgThings.append(CGDOMJSClass(descriptor))
-
- if descriptor.wrapperCache:
- cgThings.append(CGWrapWithCacheMethod(descriptor))
- cgThings.append(CGWrapMethod(descriptor))
- else:
- cgThings.append(CGWrapNonWrapperCacheMethod(descriptor))
-
- cgThings = CGList((CGIndenter(t, declareOnly=True) for t in cgThings), "\n")
- cgThings = CGWrapper(cgThings, pre='\n', post='\n')
- self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
- cgThings),
- post='\n')
-
- def declare(self):
- return self.cgRoot.declare()
- def define(self):
- return self.cgRoot.define()
-
-class CGNamespacedEnum(CGThing):
- def __init__(self, namespace, enumName, names, values, comment=""):
-
- if not values:
- values = []
-
- # Account for explicit enum values.
- entries = []
- for i in range(0, len(names)):
- if len(values) > i and values[i] is not None:
- entry = "%s = %s" % (names[i], values[i])
- else:
- entry = names[i]
- entries.append(entry)
-
- # Append a Count.
- entries.append('_' + enumName + '_Count')
-
- # Indent.
- entries = [' ' + e for e in entries]
-
- # Build the enum body.
- enumstr = comment + 'enum %s\n{\n%s\n};\n' % (enumName, ',\n'.join(entries))
- curr = CGGeneric(declare=enumstr)
-
- # Add some whitespace padding.
- curr = CGWrapper(curr, pre='\n',post='\n')
-
- # Add the namespace.
- curr = CGNamespace(namespace, curr)
-
- # Add the typedef
- typedef = '\ntypedef %s::%s %s;\n\n' % (namespace, enumName, enumName)
- curr = CGList([curr, CGGeneric(declare=typedef)])
-
- # Save the result.
- self.node = curr
-
- def declare(self):
- return self.node.declare()
- def define(self):
- assert False # Only for headers.
-
-class CGDictionary(CGThing):
- def __init__(self, dictionary, descriptorProvider):
- self.dictionary = dictionary;
- self.workers = descriptorProvider.workers
- if all(CGDictionary(d, descriptorProvider).generatable for
- d in CGDictionary.getDictionaryDependencies(dictionary)):
- self.generatable = True
- else:
- self.generatable = False
- # Nothing else to do here
- return
- # Getting a conversion template for interface types can fail
- # if we don't have a relevant descriptor when self.workers is True.
- # If that happens, just mark ourselves as not being
- # generatable and move on.
- try:
- self.memberInfo = [
- (member,
- getJSToNativeConversionTemplate(member.type,
- descriptorProvider,
- isMember=True,
- isOptional=(not member.defaultValue),
- defaultValue=member.defaultValue))
- for member in dictionary.members ]
- except NoSuchDescriptorError, err:
- if not self.workers:
- raise err
- self.generatable = False
-
- def declare(self):
- if not self.generatable:
- return ""
- d = self.dictionary
- if d.parent:
- inheritance = ": public %s " % self.makeClassName(d.parent)
- else:
- inheritance = ""
- memberDecls = [" %s %s;" %
- (self.getMemberType(m), m[0].identifier.name)
- for m in self.memberInfo]
-
- return (string.Template(
- "struct ${selfName} ${inheritance}{\n"
- " ${selfName}() {}\n"
- " bool Init(JSContext* cx, const JS::Value& val);\n"
- "\n" +
- "\n".join(memberDecls) + "\n"
- "private:\n"
- " // Disallow copy-construction\n"
- " ${selfName}(const ${selfName}&) MOZ_DELETE;\n" +
- # NOTE: jsids are per-runtime, so don't use them in workers
- (" static bool InitIds(JSContext* cx);\n"
- " static bool initedIds;\n" if not self.workers else "") +
- "\n".join(" static jsid " +
- self.makeIdName(m.identifier.name) + ";" for
- m in d.members) + "\n"
- "};").substitute( { "selfName": self.makeClassName(d),
- "inheritance": inheritance }))
-
- def define(self):
- if not self.generatable:
- return ""
- d = self.dictionary
- if d.parent:
- initParent = ("// Per spec, we init the parent's members first\n"
- "if (!%s::Init(cx, val)) {\n"
- " return false;\n"
- "}\n" % self.makeClassName(d.parent))
- else:
- initParent = ""
-
- memberInits = [CGIndenter(self.getMemberConversion(m)).define()
- for m in self.memberInfo]
- idinit = [CGGeneric('!InternJSString(cx, %s, "%s")' %
- (m.identifier.name + "_id", m.identifier.name))
- for m in d.members]
- idinit = CGList(idinit, " ||\n")
- idinit = CGWrapper(idinit, pre="if (",
- post=(") {\n"
- " return false;\n"
- "}"),
- reindent=True)
-
- return string.Template(
- # NOTE: jsids are per-runtime, so don't use them in workers
- ("bool ${selfName}::initedIds = false;\n" +
- "\n".join("jsid ${selfName}::%s = JSID_VOID;" %
- self.makeIdName(m.identifier.name)
- for m in d.members) + "\n"
- "\n"
- "bool\n"
- "${selfName}::InitIds(JSContext* cx)\n"
- "{\n"
- " MOZ_ASSERT(!initedIds);\n"
- "${idInit}\n"
- " initedIds = true;\n"
- " return true;\n"
- "}\n"
- "\n" if not self.workers else "") +
- "bool\n"
- "${selfName}::Init(JSContext* cx, const JS::Value& val)\n"
- "{\n" +
- # NOTE: jsids are per-runtime, so don't use them in workers
- (" if (!initedIds && !InitIds(cx)) {\n"
- " return false;\n"
- " }\n" if not self.workers else "") +
- "${initParent}"
- " JSBool found;\n"
- " JS::Value temp;\n"
- " bool isNull = val.isNullOrUndefined();\n"
- " if (!isNull && !val.isObject()) {\n"
- " return Throw<${isMainThread}>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
- " }\n"
- "\n"
- "${initMembers}\n"
- " return true;\n"
- "}").substitute({
- "selfName": self.makeClassName(d),
- "initParent": CGIndenter(CGGeneric(initParent)).define(),
- "initMembers": "\n\n".join(memberInits),
- "idInit": CGIndenter(idinit).define(),
- "isMainThread": toStringBool(not self.workers)
- })
-
- @staticmethod
- def makeDictionaryName(dictionary, workers):
- suffix = "Workers" if workers else ""
- return dictionary.identifier.name + suffix
-
- def makeClassName(self, dictionary):
- return self.makeDictionaryName(dictionary, self.workers)
-
- def getMemberType(self, memberInfo):
- (member, (templateBody, declType,
- holderType, dealWithOptional)) = memberInfo
- # We can't handle having a holderType here
- assert holderType is None
- if dealWithOptional:
- declType = CGWrapper(declType, pre="Optional< ", post=" >")
- return declType.define()
-
- def getMemberConversion(self, memberInfo):
- (member, (templateBody, declType,
- holderType, dealWithOptional)) = memberInfo
- replacements = { "val": "temp",
- "valPtr": "&temp",
- # Use this->%s to refer to members, because we don't
- # control the member names and want to make sure we're
- # talking about the member, not some local that
- # shadows the member. Another option would be to move
- # the guts of init to a static method which is passed
- # an explicit reference to our dictionary object, so
- # we couldn't screw this up even if we wanted to....
- "declName": ("(this->%s)" % member.identifier.name),
- # We need a holder name for external interfaces, but
- # it's scoped down to the conversion so we can just use
- # anything we want.
- "holderName": "holder"}
- # We can't handle having a holderType here
- assert holderType is None
- if dealWithOptional:
- replacements["declName"] = "(" + replacements["declName"] + ".Value())"
- if member.defaultValue:
- replacements["haveValue"] = "found"
-
- # NOTE: jsids are per-runtime, so don't use them in workers
- if self.workers:
- propName = member.identifier.name
- propCheck = ('JS_HasProperty(cx, &val.toObject(), "%s", &found)' %
- propName)
- propGet = ('JS_GetProperty(cx, &val.toObject(), "%s", &temp)' %
- propName)
- else:
- propId = self.makeIdName(member.identifier.name);
- propCheck = ("JS_HasPropertyById(cx, &val.toObject(), %s, &found)" %
- propId)
- propGet = ("JS_GetPropertyById(cx, &val.toObject(), %s, &temp)" %
- propId)
-
- conversionReplacements = {
- "prop": "(this->%s)" % member.identifier.name,
- "convert": string.Template(templateBody).substitute(replacements),
- "propCheck": propCheck,
- "propGet": propGet
- }
- conversion = ("if (isNull) {\n"
- " found = false;\n"
- "} else if (!${propCheck}) {\n"
- " return false;\n"
- "}\n")
- if member.defaultValue:
- conversion += (
- "if (found) {\n"
- " if (!${propGet}) {\n"
- " return false;\n"
- " }\n"
- "}\n"
- "${convert}")
- else:
- conversion += (
- "if (found) {\n"
- " ${prop}.Construct();\n"
- " if (!${propGet}) {\n"
- " return false;\n"
- " }\n"
- "${convert}\n"
- "}")
- conversionReplacements["convert"] = CGIndenter(
- CGGeneric(conversionReplacements["convert"])).define()
-
- return CGGeneric(
- string.Template(conversion).substitute(conversionReplacements)
- )
-
- @staticmethod
- def makeIdName(name):
- return name + "_id"
-
- @staticmethod
- def getDictionaryDependencies(dictionary):
- deps = set();
- if dictionary.parent:
- deps.add(dictionary.parent)
- for member in dictionary.members:
- if member.type.isDictionary():
- deps.add(member.type.unroll().inner)
- return deps
-
-
-class CGRegisterProtos(CGAbstractMethod):
- def __init__(self, config):
- CGAbstractMethod.__init__(self, None, 'Register', 'void',
- [Argument('nsScriptNameSpaceManager*', 'aNameSpaceManager')])
- self.config = config
-
- def _defineMacro(self):
- return """
-#define REGISTER_PROTO(_dom_class, _pref_check) \\
- aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _pref_check);\n\n"""
- def _undefineMacro(self):
- return "\n#undef REGISTER_PROTO"
- def _registerProtos(self):
- def getPrefCheck(desc):
- if desc.interface.getExtendedAttribute("PrefControlled") is None:
- return "nullptr"
- return "%sBinding::PrefEnabled" % desc.name
- lines = ["REGISTER_PROTO(%s, %s);" % (desc.name, getPrefCheck(desc))
- for desc in self.config.getDescriptors(hasInterfaceObject=True,
- isExternal=False,
- workers=False,
- register=True)]
- return '\n'.join(lines) + '\n'
- def definition_body(self):
- return self._defineMacro() + self._registerProtos() + self._undefineMacro()
-
-class CGBindingRoot(CGThing):
- """
- Root codegen class for binding generation. Instantiate the class, and call
- declare or define to generate header or cpp code (respectively).
- """
- def __init__(self, config, prefix, webIDLFile):
- descriptors = config.getDescriptors(webIDLFile=webIDLFile,
- hasInterfaceOrInterfacePrototypeObject=True)
- dictionaries = config.getDictionaries(webIDLFile)
-
- forwardDeclares = [CGClassForwardDeclare('XPCWrappedNativeScope')]
-
- descriptorsForForwardDeclaration = list(descriptors)
- for dictionary in dictionaries:
- curDict = dictionary
- ifacemembers = []
- while curDict:
- ifacemembers.extend([m.type.unroll().inner for m
- in curDict.members
- if m.type.unroll().isInterface()])
- curDict = curDict.parent
- # Put in all the non-worker descriptors
- descriptorsForForwardDeclaration.extend(
- [config.getDescriptor(iface.identifier.name, False) for
- iface in ifacemembers])
- # And now the worker ones. But these may not exist, so we
- # have to be more careful.
- for iface in ifacemembers:
- try:
- descriptorsForForwardDeclaration.append(
- config.getDescriptor(iface.identifier.name, True))
- except NoSuchDescriptorError:
- # just move along
- pass
-
- for x in descriptorsForForwardDeclaration:
- nativeType = x.nativeType
- components = x.nativeType.split('::')
- className = components[-1]
- # JSObject is a struct, not a class
- declare = CGClassForwardDeclare(className, className is "JSObject")
- if len(components) > 1:
- declare = CGNamespace.build(components[:-1],
- CGWrapper(declare, declarePre='\n',
- declarePost='\n'),
- declareOnly=True)
- forwardDeclares.append(CGWrapper(declare, declarePost='\n'))
-
- forwardDeclares = CGList(forwardDeclares)
-
- descriptorsWithPrototype = filter(lambda d: d.interface.hasInterfacePrototypeObject(),
- descriptors)
- traitsClasses = [CGPrototypeTraitsClass(d) for d in descriptorsWithPrototype]
-
- # We must have a 1:1 mapping here, skip for prototypes that have more
- # than one concrete class implementation.
- traitsClasses.extend([CGPrototypeIDMapClass(d) for d in descriptorsWithPrototype
- if d.uniqueImplementation])
-
- # Wrap all of that in our namespaces.
- if len(traitsClasses) > 0:
- traitsClasses = CGNamespace.build(['mozilla', 'dom'],
- CGWrapper(CGList(traitsClasses),
- declarePre='\n'),
- declareOnly=True)
- traitsClasses = CGWrapper(traitsClasses, declarePost='\n')
- else:
- traitsClasses = None
-
- # Do codegen for all the enums
- def makeEnum(e):
- return CGNamespace.build([e.identifier.name + "Values"],
- CGEnum(e))
- def makeEnumTypedef(e):
- return CGGeneric(declare=("typedef %sValues::valuelist %s;\n" %
- (e.identifier.name, e.identifier.name)))
- cgthings = [ fun(e) for e in config.getEnums(webIDLFile)
- for fun in [makeEnum, makeEnumTypedef] ]
-
- # Do codegen for all the dictionaries. We have to be a bit careful
- # here, because we have to generate these in order from least derived
- # to most derived so that class inheritance works out. We also have to
- # generate members before the dictionary that contains them.
- #
- # XXXbz this will fail if we have two webidl files A and B such that A
- # declares a dictionary which inherits from a dictionary in B and B
- # declares a dictionary (possibly a different one!) that inherits from a
- # dictionary in A. The good news is that I expect this to never happen.
- reSortedDictionaries = []
- dictionaries = set(dictionaries)
- while len(dictionaries) != 0:
- # Find the dictionaries that don't depend on anything else anymore
- # and move them over.
- toMove = [d for d in dictionaries if
- len(CGDictionary.getDictionaryDependencies(d) &
- dictionaries) == 0]
- if len(toMove) == 0:
- raise TypeError("Loop in dictionary dependency graph")
- dictionaries = dictionaries - set(toMove)
- reSortedDictionaries.extend(toMove)
-
- dictionaries = reSortedDictionaries
- cgthings.extend([CGDictionary(d, config.getDescriptorProvider(True))
- for d in dictionaries])
- cgthings.extend([CGDictionary(d, config.getDescriptorProvider(False))
- for d in dictionaries])
-
- # Do codegen for all the descriptors
- cgthings.extend([CGDescriptor(x) for x in descriptors])
-
- # And make sure we have the right number of newlines at the end
- curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
-
- # Wrap all of that in our namespaces.
- curr = CGNamespace.build(['mozilla', 'dom'],
- CGWrapper(curr, pre="\n"))
-
- curr = CGList([forwardDeclares,
- CGWrapper(CGGeneric("using namespace mozilla::dom;"),
- defineOnly=True),
- traitsClasses, curr],
- "\n")
-
- # Add header includes.
- curr = CGHeaders(descriptors,
- dictionaries,
- ['mozilla/dom/BindingUtils.h',
- 'mozilla/dom/DOMJSClass.h',
- 'mozilla/dom/DOMJSProxyHandler.h'],
- ['mozilla/dom/Nullable.h',
- 'PrimitiveConversions.h',
- 'XPCQuickStubs.h',
- 'nsDOMQS.h',
- 'AccessCheck.h',
- 'WorkerPrivate.h',
- 'nsContentUtils.h',
- 'mozilla/Preferences.h',
- # Have to include nsDOMQS.h to get fast arg unwrapping
- # for old-binding things with castability.
- 'nsDOMQS.h'
- ],
- curr)
-
- # Add include guards.
- curr = CGIncludeGuard(prefix, curr)
-
- # Add the auto-generated comment.
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
-
- # Store the final result.
- self.root = curr
-
- def declare(self):
- return stripTrailingWhitespace(self.root.declare())
- def define(self):
- return stripTrailingWhitespace(self.root.define())
-
-
-class GlobalGenRoots():
- """
- Roots for global codegen.
-
- To generate code, call the method associated with the target, and then
- call the appropriate define/declare method.
- """
-
- @staticmethod
- def PrototypeList(config):
-
- # Prototype ID enum.
- protos = [d.name for d in config.getDescriptors(hasInterfacePrototypeObject=True)]
- idEnum = CGNamespacedEnum('id', 'ID', protos, [0])
- idEnum = CGList([idEnum])
- idEnum.append(CGGeneric(declare="const unsigned MaxProtoChainLength = " +
- str(config.maxProtoChainLength) + ";\n\n"))
-
- # Wrap all of that in our namespaces.
- idEnum = CGNamespace.build(['mozilla', 'dom', 'prototypes'],
- CGWrapper(idEnum, pre='\n'))
- idEnum = CGWrapper(idEnum, post='\n')
-
- curr = CGList([idEnum])
-
- # Constructor ID enum.
- constructors = [d.name for d in config.getDescriptors(hasInterfaceObject=True,
- hasInterfacePrototypeObject=False)]
- idEnum = CGNamespacedEnum('id', 'ID', constructors, [0])
-
- # Wrap all of that in our namespaces.
- idEnum = CGNamespace.build(['mozilla', 'dom', 'constructors'],
- CGWrapper(idEnum, pre='\n'))
- idEnum = CGWrapper(idEnum, post='\n')
-
- curr.append(idEnum)
-
- traitsDecl = CGGeneric(declare="""
-template <prototypes::ID PrototypeID>
-struct PrototypeTraits;
-
-template <class ConcreteClass>
-struct PrototypeIDMap;
-""")
-
- traitsDecl = CGNamespace.build(['mozilla', 'dom'],
- CGWrapper(traitsDecl, post='\n'))
-
- curr.append(traitsDecl)
-
- # Add include guards.
- curr = CGIncludeGuard('PrototypeList', curr)
-
- # Add the auto-generated comment.
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
-
- # Done.
- return curr
-
- @staticmethod
- def RegisterBindings(config):
-
- # TODO - Generate the methods we want
- curr = CGRegisterProtos(config)
-
- # Wrap all of that in our namespaces.
- curr = CGNamespace.build(['mozilla', 'dom'],
- CGWrapper(curr, post='\n'))
- curr = CGWrapper(curr, post='\n')
-
- # Add the includes
- defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
- for desc in config.getDescriptors(hasInterfaceObject=True,
- workers=False,
- register=True)]
- defineIncludes.append('nsScriptNameSpaceManager.h')
- curr = CGHeaders([], [], [], defineIncludes, curr)
-
- # Add include guards.
- curr = CGIncludeGuard('RegisterBindings', curr)
-
- # Done.
- return curr
-
- @staticmethod
- def UnionTypes(config):
-
- (includes, declarations, unions) = UnionTypes(config.getDescriptors())
- includes.add("mozilla/dom/BindingUtils.h")
-
- # Wrap all of that in our namespaces.
- curr = CGNamespace.build(['mozilla', 'dom'], unions)
-
- curr = CGWrapper(curr, post='\n')
-
- namespaces = []
- stack = [CGList([])]
- for (clazz, isStruct) in SortedTuples(declarations):
- elements = clazz.split("::")
- clazz = CGClassForwardDeclare(elements.pop(), isStruct=isStruct)
- i = 0
- if len(elements) > 0:
- common = min(len(namespaces), len(elements))
- while i < common and namespaces[i] == elements[i]:
- i += 1
-
- # pop all the namespaces that should be closed
- namespaces = namespaces[:i]
-
- # add all the namespaces that should be opened
- for j, namespace in enumerate(elements[i:]):
- namespaces.append(namespace)
- # every CGNamespace that we add holds a CGList
- list = CGList([])
- # add the new namespace to the list on top of the stack
- stack[i + j].append(CGNamespace(namespace, list))
- # set the top of the namespace stack to the list of the new
- # namespace
- stack[i + j + 1:] = [list]
-
- stack[len(elements)].append(clazz)
-
- curr = CGList([stack[0], curr], "\n")
-
- curr = CGHeaders([], [], includes, [], curr)
-
- # Add include guards.
- curr = CGIncludeGuard('UnionTypes', curr)
-
- # Done.
- return curr
-
- @staticmethod
- def UnionConversions(config):
-
- unions = UnionConversions(config.getDescriptors())
-
- # Wrap all of that in our namespaces.
- curr = CGNamespace.build(['mozilla', 'dom'], unions)
-
- curr = CGWrapper(curr, post='\n')
-
- curr = CGHeaders([], [], ["nsDebug.h", "mozilla/dom/UnionTypes.h", "nsDOMQS.h"], [], curr)
-
- # Add include guards.
- curr = CGIncludeGuard('UnionConversions', curr)
-
- # Done.
- return curr
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
deleted file mode 100644
index 1666589940e..00000000000
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ /dev/null
@@ -1,5534 +0,0 @@
-# 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/.
-
-# Common codegen classes.
-
-import operator
-import os
-import re
-import string
-
-from WebIDL import (
- BuiltinTypes,
- IDLBuiltinType,
- IDLNullValue,
- IDLType,
- IDLUndefinedValue,
-)
-
-from Configuration import getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback
-
-AUTOGENERATED_WARNING_COMMENT = \
- "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
-ADDPROPERTY_HOOK_NAME = '_addProperty'
-FINALIZE_HOOK_NAME = '_finalize'
-TRACE_HOOK_NAME = '_trace'
-CONSTRUCT_HOOK_NAME = '_constructor'
-HASINSTANCE_HOOK_NAME = '_hasInstance'
-
-def replaceFileIfChanged(filename, newContents):
- """
- Read a copy of the old file, so that we don't touch it if it hasn't changed.
- Returns True if the file was updated, false otherwise.
- """
- #XXXjdm This doesn't play well with make right now.
- # Force the file to always be updated, or else changing CodegenRust.py
- # will cause many autogenerated bindings to be regenerated perpetually
- # until the result is actually different.
-
- #oldFileContents = ""
- #try:
- # oldFile = open(filename, 'rb')
- # oldFileContents = ''.join(oldFile.readlines())
- # oldFile.close()
- #except:
- # pass
-
- #if newContents == oldFileContents:
- # return False
-
- f = open(filename, 'wb')
- f.write(newContents)
- f.close()
-
- return True
-
-def toStringBool(arg):
- return str(not not arg).lower()
-
-def toBindingNamespace(arg):
- return re.sub("((_workers)?$)", "Binding\\1", arg);
-
-def stripTrailingWhitespace(text):
- tail = '\n' if text.endswith('\n') else ''
- lines = text.splitlines()
- for i in range(len(lines)):
- lines[i] = lines[i].rstrip()
- return '\n'.join(lines) + tail
-
-def MakeNativeName(name):
- return name[0].upper() + name[1:]
-
-builtinNames = {
- IDLType.Tags.bool: 'bool',
- IDLType.Tags.int8: 'i8',
- IDLType.Tags.int16: 'i16',
- IDLType.Tags.int32: 'i32',
- IDLType.Tags.int64: 'i64',
- IDLType.Tags.uint8: 'u8',
- IDLType.Tags.uint16: 'u16',
- IDLType.Tags.uint32: 'u32',
- IDLType.Tags.uint64: 'u64',
- IDLType.Tags.float: 'f32',
- IDLType.Tags.double: 'f64'
-}
-
-numericTags = [
- IDLType.Tags.int8, IDLType.Tags.uint8,
- IDLType.Tags.int16, IDLType.Tags.uint16,
- IDLType.Tags.int32, IDLType.Tags.uint32,
- IDLType.Tags.int64, IDLType.Tags.uint64,
- IDLType.Tags.float, IDLType.Tags.double
- ]
-
-class CastableObjectUnwrapper():
- """
- A class for unwrapping an object named by the "source" argument
- based on the passed-in descriptor. Stringifies to a Rust expression of
- the appropriate type.
-
- codeOnFailure is the code to run if unwrapping fails.
- """
- def __init__(self, descriptor, source, codeOnFailure):
- self.substitution = {
- "type": descriptor.nativeType,
- "depth": descriptor.interface.inheritanceDepth(),
- "prototype": "PrototypeList::id::" + descriptor.name,
- "protoID": "PrototypeList::id::" + descriptor.name + " as uint",
- "source": source,
- "codeOnFailure": CGIndenter(CGGeneric(codeOnFailure), 4).define(),
- }
-
- def __str__(self):
- return string.Template(
-"""match unwrap_jsmanaged(${source}, ${prototype}, ${depth}) {
- Ok(val) => val,
- Err(()) => {
-${codeOnFailure}
- }
-}""").substitute(self.substitution)
-
-
-class CGThing():
- """
- Abstract base class for things that spit out code.
- """
- def __init__(self):
- pass # Nothing for now
-
- def define(self):
- """Produce code for a Rust file."""
- assert(False) # Override me!
-
-
-class CGNativePropertyHooks(CGThing):
- """
- Generate a NativePropertyHooks for a given descriptor
- """
- def __init__(self, descriptor, properties):
- CGThing.__init__(self)
- self.descriptor = descriptor
- self.properties = properties
-
- def define(self):
- parent = self.descriptor.interface.parent
- if parent:
- parentHooks = "Some(&::dom::bindings::codegen::Bindings::%sBinding::sNativePropertyHooks)" % parent.identifier.name
- else:
- parentHooks = "None"
-
- substitutions = {
- "parentHooks": parentHooks
- }
-
- return string.Template(
- "pub static sNativePropertyHooks: NativePropertyHooks = NativePropertyHooks {\n"
- " native_properties: &sNativeProperties,\n"
- " proto_hooks: ${parentHooks},\n"
- "};\n").substitute(substitutions)
-
-
-class CGMethodCall(CGThing):
- """
- A class to generate selection of a method signature from a set of
- signatures and generation of a call to that signature.
- """
- def __init__(self, argsPre, nativeMethodName, static, descriptor, method):
- CGThing.__init__(self)
-
- methodName = '\\"%s.%s\\"' % (descriptor.interface.identifier.name, method.identifier.name)
-
- def requiredArgCount(signature):
- arguments = signature[1]
- if len(arguments) == 0:
- return 0
- requiredArgs = len(arguments)
- while requiredArgs and arguments[requiredArgs-1].optional:
- requiredArgs -= 1
- return requiredArgs
-
- def getPerSignatureCall(signature, argConversionStartsAt=0, signatureIndex=0):
- return CGPerSignatureCall(signature[0], argsPre, signature[1],
- nativeMethodName + '_'*signatureIndex,
- static, descriptor,
- method, argConversionStartsAt)
-
-
- signatures = method.signatures()
- if len(signatures) == 1:
- # Special case: we can just do a per-signature method call
- # here for our one signature and not worry about switching
- # on anything.
- signature = signatures[0]
- self.cgRoot = CGList([getPerSignatureCall(signature)])
- requiredArgs = requiredArgCount(signature)
-
-
- if requiredArgs > 0:
- code = (
- "if argc < %d {\n"
- " throw_type_error(cx, \"Not enough arguments to %s.\");\n"
- " return 0;\n"
- "}" % (requiredArgs, methodName))
- self.cgRoot.prepend(
- CGWrapper(CGGeneric(code), pre="\n", post="\n"))
-
- return
-
- # Need to find the right overload
- maxArgCount = method.maxArgCount
- allowedArgCounts = method.allowedArgCounts
-
- argCountCases = []
- for argCount in allowedArgCounts:
- possibleSignatures = method.signaturesForArgCount(argCount)
- if len(possibleSignatures) == 1:
- # easy case!
- signature = possibleSignatures[0]
-
-
- sigIndex = signatures.index(signature)
- argCountCases.append(
- CGCase(str(argCount), getPerSignatureCall(signature,
- signatureIndex=sigIndex)))
- continue
-
- distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
-
- # We can't handle unions at the distinguishing index.
- for (returnType, args) in possibleSignatures:
- if args[distinguishingIndex].type.isUnion():
- raise TypeError("No support for unions as distinguishing "
- "arguments yet: %s",
- args[distinguishingIndex].location)
-
- # Convert all our arguments up to the distinguishing index.
- # Doesn't matter which of the possible signatures we use, since
- # they all have the same types up to that point; just use
- # possibleSignatures[0]
- caseBody = [CGGeneric("let argv_start = JS_ARGV(cx, vp);")]
- caseBody.extend([ CGArgumentConverter(possibleSignatures[0][1][i],
- i, "argv_start", "argc",
- descriptor) for i in
- range(0, distinguishingIndex) ])
-
- # Select the right overload from our set.
- distinguishingArg = "(*argv_start.offset(%d))" % distinguishingIndex
-
- def pickFirstSignature(condition, filterLambda):
- sigs = filter(filterLambda, possibleSignatures)
- assert len(sigs) < 2
- if len(sigs) > 0:
- if condition is None:
- caseBody.append(
- getPerSignatureCall(sigs[0], distinguishingIndex,
- possibleSignatures.index(sigs[0])))
- else:
- caseBody.append(CGGeneric("if " + condition + " {"))
- caseBody.append(CGIndenter(
- getPerSignatureCall(sigs[0], distinguishingIndex,
- possibleSignatures.index(sigs[0]))))
- caseBody.append(CGGeneric("}"))
- return True
- return False
-
- # First check for null or undefined
- pickFirstSignature("%s.isNullOrUndefined()" % distinguishingArg,
- lambda s: (s[1][distinguishingIndex].type.nullable() or
- s[1][distinguishingIndex].type.isDictionary()))
-
- # Now check for distinguishingArg being an object that implements a
- # non-callback interface. That includes typed arrays and
- # arraybuffers.
- interfacesSigs = [
- s for s in possibleSignatures
- if (s[1][distinguishingIndex].type.isObject() or
- s[1][distinguishingIndex].type.isNonCallbackInterface()) ]
- # There might be more than one of these; we need to check
- # which ones we unwrap to.
-
- if len(interfacesSigs) > 0:
- # The spec says that we should check for "platform objects
- # implementing an interface", but it's enough to guard on these
- # being an object. The code for unwrapping non-callback
- # interfaces and typed arrays will just bail out and move on to
- # the next overload if the object fails to unwrap correctly. We
- # could even not do the isObject() check up front here, but in
- # cases where we have multiple object overloads it makes sense
- # to do it only once instead of for each overload. That will
- # also allow the unwrapping test to skip having to do codegen
- # for the null-or-undefined case, which we already handled
- # above.
- caseBody.append(CGGeneric("if (%s).is_object() {" %
- (distinguishingArg)))
- for idx, sig in enumerate(interfacesSigs):
- caseBody.append(CGIndenter(CGGeneric("loop {")));
- type = sig[1][distinguishingIndex].type
-
- # The argument at index distinguishingIndex can't possibly
- # be unset here, because we've already checked that argc is
- # large enough that we can examine this argument.
- template, _, declType, needsRooting = getJSToNativeConversionTemplate(
- type, descriptor, failureCode="break;", isDefinitelyObject=True)
-
- testCode = instantiateJSToNativeConversionTemplate(
- template,
- {"val": distinguishingArg},
- declType,
- "arg%d" % distinguishingIndex,
- needsRooting)
-
- # Indent by 4, since we need to indent further than our "do" statement
- caseBody.append(CGIndenter(testCode, 4));
- # If we got this far, we know we unwrapped to the right
- # interface, so just do the call. Start conversion with
- # distinguishingIndex + 1, since we already converted
- # distinguishingIndex.
- caseBody.append(CGIndenter(
- getPerSignatureCall(sig, distinguishingIndex + 1, idx), 4))
- caseBody.append(CGIndenter(CGGeneric("}")))
-
- caseBody.append(CGGeneric("}"))
-
- # XXXbz Now we're supposed to check for distinguishingArg being
- # an array or a platform object that supports indexed
- # properties... skip that last for now. It's a bit of a pain.
- pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject())" %
- (distinguishingArg, distinguishingArg),
- lambda s:
- (s[1][distinguishingIndex].type.isArray() or
- s[1][distinguishingIndex].type.isSequence() or
- s[1][distinguishingIndex].type.isObject()))
-
- # Check for Date objects
- # XXXbz Do we need to worry about security wrappers around the Date?
- pickFirstSignature("%s.isObject() && JS_ObjectIsDate(cx, &%s.toObject())" %
- (distinguishingArg, distinguishingArg),
- lambda s: (s[1][distinguishingIndex].type.isDate() or
- s[1][distinguishingIndex].type.isObject()))
-
- # Check for vanilla JS objects
- # XXXbz Do we need to worry about security wrappers?
- pickFirstSignature("%s.isObject() && !IsPlatformObject(cx, &%s.toObject())" %
- (distinguishingArg, distinguishingArg),
- lambda s: (s[1][distinguishingIndex].type.isCallback() or
- s[1][distinguishingIndex].type.isCallbackInterface() or
- s[1][distinguishingIndex].type.isDictionary() or
- s[1][distinguishingIndex].type.isObject()))
-
- # The remaining cases are mutually exclusive. The
- # pickFirstSignature calls are what change caseBody
- # Check for strings or enums
- if pickFirstSignature(None,
- lambda s: (s[1][distinguishingIndex].type.isString() or
- s[1][distinguishingIndex].type.isEnum())):
- pass
- # Check for primitives
- elif pickFirstSignature(None,
- lambda s: s[1][distinguishingIndex].type.isPrimitive()):
- pass
- # Check for "any"
- elif pickFirstSignature(None,
- lambda s: s[1][distinguishingIndex].type.isAny()):
- pass
- else:
- # Just throw; we have no idea what we're supposed to
- # do with this.
- caseBody.append(CGGeneric("return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);"))
-
- argCountCases.append(CGCase(str(argCount),
- CGList(caseBody, "\n")))
-
- overloadCGThings = []
- overloadCGThings.append(
- CGGeneric("let argcount = cmp::min(argc, %d);" %
- maxArgCount))
- overloadCGThings.append(
- CGSwitch("argcount",
- argCountCases,
- CGGeneric("throw_type_error(cx, \"Not enough arguments to %s.\");\n"
- "return 0;\n" % methodName)))
- #XXXjdm Avoid unreachable statement warnings
- #overloadCGThings.append(
- # CGGeneric('fail!("We have an always-returning default case");\n'
- # 'return 0;'))
- self.cgRoot = CGWrapper(CGList(overloadCGThings, "\n"),
- pre="\n")
-
- def define(self):
- return self.cgRoot.define()
-
-class FakeCastableDescriptor():
- def __init__(self, descriptor):
- self.nativeType = "*const %s" % descriptor.concreteType
- self.name = descriptor.name
- class FakeInterface:
- def inheritanceDepth(self):
- return descriptor.interface.inheritanceDepth()
- self.interface = FakeInterface()
-
-def dictionaryHasSequenceMember(dictionary):
- return (any(typeIsSequenceOrHasSequenceMember(m.type) for m in
- dictionary.members) or
- (dictionary.parent and
- dictionaryHasSequenceMember(dictionary.parent)))
-
-def typeIsSequenceOrHasSequenceMember(type):
- if type.nullable():
- type = type.inner
- if type.isSequence():
- return True
- if type.isArray():
- elementType = type.inner
- return typeIsSequenceOrHasSequenceMember(elementType)
- if type.isDictionary():
- return dictionaryHasSequenceMember(type.inner)
- if type.isUnion():
- return any(typeIsSequenceOrHasSequenceMember(m.type) for m in
- type.flatMemberTypes)
- return False
-
-def typeNeedsRooting(type, descriptorProvider):
- return type.isGeckoInterface() and descriptorProvider.getDescriptor(type.name).needsRooting
-
-def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
- isDefinitelyObject=False,
- isMember=False,
- isArgument=False,
- invalidEnumValueFatal=True,
- defaultValue=None,
- treatNullAs="Default",
- isEnforceRange=False,
- isClamp=False,
- exceptionCode=None,
- allowTreatNonObjectAsNull=False,
- isCallbackReturnValue=False,
- sourceDescription="value"):
- """
- Get a template for converting a JS value to a native object based on the
- given type and descriptor. If failureCode is given, then we're actually
- testing whether we can convert the argument to the desired type. That
- means that failures to convert due to the JS value being the wrong type of
- value need to use failureCode instead of throwing exceptions. Failures to
- convert that are due to JS exceptions (from toString or valueOf methods) or
- out of memory conditions need to throw exceptions no matter what
- failureCode is.
-
- If isDefinitelyObject is True, that means we know the value
- isObject() and we have no need to recheck that.
-
- if isMember is True, we're being converted from a property of some
- JS object, not from an actual method argument, so we can't rely on
- our jsval being rooted or outliving us in any way. Any caller
- passing true needs to ensure that it is handled correctly in
- typeIsSequenceOrHasSequenceMember.
-
- invalidEnumValueFatal controls whether an invalid enum value conversion
- attempt will throw (if true) or simply return without doing anything (if
- false).
-
- If defaultValue is not None, it's the IDL default value for this conversion
-
- If isEnforceRange is true, we're converting an integer and throwing if the
- value is out of range.
-
- If isClamp is true, we're converting an integer and clamping if the
- value is out of range.
-
- If allowTreatNonObjectAsNull is true, then [TreatNonObjectAsNull]
- extended attributes on nullable callback functions will be honored.
-
- The return value from this function is a tuple consisting of four things:
-
- 1) A string representing the conversion code. This will have template
- substitution performed on it as follows:
-
- ${val} replaced by an expression for the JS::Value in question
-
- 2) A string or None representing Rust code for the default value (if any).
-
- 3) A CGThing representing the native C++ type we're converting to
- (declType). This is allowed to be None if the conversion code is
- supposed to be used as-is.
-
- 4) A boolean indicating whether the caller has to root the result.
-
- """
- # We should not have a defaultValue if we know we're an object
- assert(not isDefinitelyObject or defaultValue is None)
-
- # If exceptionCode is not set, we'll just rethrow the exception we got.
- # Note that we can't just set failureCode to exceptionCode, because setting
- # failureCode will prevent pending exceptions from being set in cases when
- # they really should be!
- if exceptionCode is None:
- exceptionCode = "return 0;"
-
- needsRooting = typeNeedsRooting(type, descriptorProvider)
-
- def handleOptional(template, declType, default):
- assert (defaultValue is None) == (default is None)
- return (template, default, declType, needsRooting)
-
- # Unfortunately, .capitalize() on a string will lowercase things inside the
- # string, which we do not want.
- def firstCap(string):
- return string[0].upper() + string[1:]
-
- # Helper functions for dealing with failures due to the JS value being the
- # wrong type of value
- # Helper functions for dealing with failures due to the JS value being the
- # wrong type of value
- def onFailureNotAnObject(failureCode):
- return CGWrapper(
- CGGeneric(
- failureCode or
- ('throw_type_error(cx, "%s is not an object.");\n'
- '%s' % (firstCap(sourceDescription), exceptionCode))),
- post="\n")
- def onFailureBadType(failureCode, typeName):
- return CGWrapper(
- CGGeneric(
- failureCode or
- ('throw_type_error(cx, \"%s does not implement interface %s.\");\n'
- '%s' % (firstCap(sourceDescription), typeName,
- exceptionCode))),
- post="\n")
- def onFailureNotCallable(failureCode):
- return CGWrapper(
- CGGeneric(
- failureCode or
- ('throw_type_error(cx, \"%s is not callable.\");\n'
- '%s' % (firstCap(sourceDescription), exceptionCode))),
- post="\n")
-
-
- # A helper function for handling null default values. Checks that the
- # default value, if it exists, is null.
- def handleDefaultNull(nullValue):
- if defaultValue is None:
- return None
-
- if not isinstance(defaultValue, IDLNullValue):
- raise TypeError("Can't handle non-null default value here")
-
- assert type.nullable() or type.isDictionary()
- return nullValue
-
- # A helper function for wrapping up the template body for
- # possibly-nullable objecty stuff
- def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
- failureCode=None):
- if not isDefinitelyObject:
- # Handle the non-object cases by wrapping up the whole
- # thing in an if cascade.
- templateBody = (
- "if (${val}).is_object() {\n" +
- CGIndenter(CGGeneric(templateBody)).define() + "\n")
- if type.nullable():
- templateBody += (
- "} else if (${val}).is_null_or_undefined() {\n"
- " None\n")
- templateBody += (
- "} else {\n" +
- CGIndenter(onFailureNotAnObject(failureCode)).define() +
- "}\n")
-
- return templateBody
-
- assert not (isEnforceRange and isClamp) # These are mutually exclusive
-
- if type.isArray():
- raise TypeError("Can't handle array arguments yet")
-
- if type.isSequence():
- raise TypeError("Can't handle sequence arguments yet")
-
- if type.isUnion():
- declType = CGGeneric(type.name + "::" + type.name)
- if type.nullable():
- declType = CGWrapper(declType, pre="Option<", post=" >")
-
- templateBody = ("match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n"
- " Ok(value) => value,\n"
- " Err(()) => { %s },\n"
- "}" % exceptionCode)
-
- return handleOptional(templateBody, declType, handleDefaultNull("None"))
-
- if type.isGeckoInterface():
- assert not isEnforceRange and not isClamp
-
- descriptor = descriptorProvider.getDescriptor(
- type.unroll().inner.identifier.name)
-
- if descriptor.interface.isCallback():
- name = descriptor.nativeType
- declType = CGGeneric("Option<%s>" % name);
- conversion = ("Some(%s::new((${val}).to_object()))" % name)
-
- template = wrapObjectTemplate(conversion, isDefinitelyObject, type,
- failureCode)
- return handleOptional(template, declType, handleDefaultNull("None"))
-
- if isMember:
- descriptorType = descriptor.memberType
- elif isArgument:
- descriptorType = descriptor.argumentType
- else:
- descriptorType = descriptor.nativeType
-
- templateBody = ""
- if descriptor.interface.isConsequential():
- raise TypeError("Consequential interface %s being used as an "
- "argument" % descriptor.interface.identifier.name)
-
- if failureCode is None:
- substitutions = {
- "sourceDescription": sourceDescription,
- "interface": descriptor.interface.identifier.name,
- "exceptionCode": exceptionCode,
- }
- unwrapFailureCode = string.Template(
- 'throw_type_error(cx, "${sourceDescription} does not '
- 'implement interface ${interface}.");\n'
- '${exceptionCode}').substitute(substitutions)
- else:
- unwrapFailureCode = failureCode
-
- templateBody = str(CastableObjectUnwrapper(
- descriptor,
- "(${val}).to_object()",
- unwrapFailureCode))
-
- declType = CGGeneric(descriptorType)
- if type.nullable():
- templateBody = "Some(%s)" % templateBody
- declType = CGWrapper(declType, pre="Option<", post=">")
-
- if isMember:
- templateBody += ".root()"
-
- templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
- type, failureCode)
-
- return handleOptional(templateBody, declType, handleDefaultNull("None"))
-
- if type.isSpiderMonkeyInterface():
- raise TypeError("Can't handle SpiderMonkey interface arguments yet")
-
- if type.isDOMString():
- assert not isEnforceRange and not isClamp
-
- treatAs = {
- "Default": "Default",
- "EmptyString": "Empty",
- }
- if treatNullAs not in treatAs:
- raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs)
- if type.nullable():
- nullBehavior = "()"
- else:
- nullBehavior = treatAs[treatNullAs]
-
- conversionCode = (
- "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n"
- " Ok(strval) => strval,\n"
- " Err(_) => { %s },\n"
- "}" % (nullBehavior, exceptionCode))
-
- if defaultValue is None:
- default = None
- elif isinstance(defaultValue, IDLNullValue):
- assert type.nullable()
- default = "None"
- else:
- assert defaultValue.type.tag() == IDLType.Tags.domstring
- value = "str::from_utf8(data).unwrap().to_string()"
- if type.nullable():
- value = "Some(%s)" % value
-
- default = (
- "static data: [u8, ..%s] = [ %s ];\n"
- "%s" %
- (len(defaultValue.value) + 1,
- ", ".join(["'" + char + "' as u8" for char in defaultValue.value] + ["0"]),
- value))
-
- declType = "DOMString"
- if type.nullable():
- declType = "Option<%s>" % declType
-
- return handleOptional(conversionCode, CGGeneric(declType), default)
-
- if type.isByteString():
- assert not isEnforceRange and not isClamp
-
- conversionCode = (
- "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n"
- " Ok(strval) => strval,\n"
- " Err(_) => { %s },\n"
- "}" % exceptionCode)
-
- declType = CGGeneric("ByteString")
- if type.nullable():
- declType = CGWrapper(declType, pre="Option<", post=">")
-
- return handleOptional(conversionCode, declType, handleDefaultNull("None"))
-
- if type.isEnum():
- assert not isEnforceRange and not isClamp
-
- if type.nullable():
- raise TypeError("We don't support nullable enumerated arguments "
- "yet")
- enum = type.inner.identifier.name
- if invalidEnumValueFatal:
- handleInvalidEnumValueCode = exceptionCode
- else:
- handleInvalidEnumValueCode = "return 1;"
-
- template = (
- "match FindEnumStringIndex(cx, ${val}, %(values)s) {\n"
- " Err(_) => { %(exceptionCode)s },\n"
- " Ok(None) => { %(handleInvalidEnumValueCode)s },\n"
- " Ok(Some(index)) => {\n"
- " //XXXjdm need some range checks up in here.\n"
- " unsafe { mem::transmute(index) }\n"
- " },\n"
- "}" % { "values" : enum + "Values::strings",
- "exceptionCode" : exceptionCode,
-"handleInvalidEnumValueCode" : handleInvalidEnumValueCode })
-
- if defaultValue is not None:
- assert(defaultValue.type.tag() == IDLType.Tags.domstring)
- default = "%sValues::%s" % (enum, getEnumValueName(defaultValue.value))
- else:
- default = None
-
- return handleOptional(template, CGGeneric(enum), default)
-
- if type.isCallback():
- assert not isEnforceRange and not isClamp
- assert not type.treatNonCallableAsNull()
- assert not type.treatNonObjectAsNull() or type.nullable()
- assert not type.treatNonObjectAsNull() or not type.treatNonCallableAsNull()
-
- declType = CGGeneric('%s::%s' % (type.unroll().module(), type.unroll().identifier.name))
-
- conversion = CGCallbackTempRoot(declType.define())
-
- if type.nullable():
- declType = CGTemplatedType("Option", declType)
- conversion = CGWrapper(conversion, pre="Some(", post=")")
-
- if allowTreatNonObjectAsNull and type.treatNonObjectAsNull():
- if not isDefinitelyObject:
- haveObject = "${val}.is_object()"
- template = CGIfElseWrapper(haveObject,
- conversion,
- CGGeneric("None")).define()
- else:
- template = conversion
- else:
- template = CGIfElseWrapper("JS_ObjectIsCallable(cx, ${val}.to_object()) != 0",
- conversion,
- onFailureNotCallable(failureCode)).define()
- template = wrapObjectTemplate(
- template,
- isDefinitelyObject,
- type,
- failureCode)
-
- if defaultValue is not None:
- assert allowTreatNonObjectAsNull
- assert type.treatNonObjectAsNull()
- assert type.nullable()
- assert isinstance(defaultValue, IDLNullValue)
- default = "None"
- else:
- default = None
-
- return (template, default, declType, needsRooting)
-
- if type.isAny():
- assert not isEnforceRange and not isClamp
-
- declType = CGGeneric("JSVal")
-
- if defaultValue is None:
- default = None
- elif isinstance(defaultValue, IDLNullValue):
- default = "NullValue()"
- elif isinstance(defaultValue, IDLUndefinedValue):
- default = "UndefinedValue()"
- else:
- raise TypeError("Can't handle non-null, non-undefined default value here")
-
- return handleOptional("${val}", declType, default)
-
- if type.isObject():
- raise TypeError("Can't handle object arguments yet")
-
- if type.isDictionary():
- if failureCode is not None:
- raise TypeError("Can't handle dictionaries when failureCode is not None")
- # There are no nullable dictionaries
- assert not type.nullable()
-
- typeName = CGDictionary.makeDictionaryName(type.inner)
- declType = CGGeneric(typeName)
- template = ("match %s::new(cx, ${val}) {\n"
- " Ok(dictionary) => dictionary,\n"
- " Err(_) => return 0,\n"
- "}" % typeName)
-
- return handleOptional(template, declType, handleDefaultNull("%s::empty()" % typeName))
-
- if type.isVoid():
- # This one only happens for return values, and its easy: Just
- # ignore the jsval.
- return ("", None, None, False)
-
- if not type.isPrimitive():
- raise TypeError("Need conversion for argument type '%s'" % str(type))
-
- assert not isEnforceRange and not isClamp
-
- if failureCode is None:
- failureCode = 'return 0'
-
- declType = CGGeneric(builtinNames[type.tag()])
- if type.nullable():
- declType = CGWrapper(declType, pre="Option<", post=">")
-
- #XXXjdm support conversionBehavior here
- template = (
- "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n"
- " Ok(v) => v,\n"
- " Err(_) => { %s }\n"
- "}" % exceptionCode)
-
- if defaultValue is not None:
- if isinstance(defaultValue, IDLNullValue):
- assert type.nullable()
- defaultStr = "None"
- else:
- tag = defaultValue.type.tag()
- if tag in numericTags:
- defaultStr = str(defaultValue.value)
- else:
- assert(tag == IDLType.Tags.bool)
- defaultStr = toStringBool(defaultValue.value)
-
- if type.nullable():
- defaultStr = "Some(%s)" % defaultStr
- else:
- defaultStr = None
-
- return handleOptional(template, declType, defaultStr)
-
-def instantiateJSToNativeConversionTemplate(templateBody, replacements,
- declType, declName, needsRooting):
- """
- Take the templateBody and declType as returned by
- getJSToNativeConversionTemplate, a set of replacements as required by the
- strings in such a templateBody, and a declName, and generate code to
- convert into a stack Rust binding with that name.
- """
- result = CGList([], "\n")
-
- conversion = CGGeneric(
- string.Template(templateBody).substitute(replacements)
- )
-
- if declType is not None:
- newDecl = [
- CGGeneric("let "),
- CGGeneric(declName),
- CGGeneric(": "),
- declType,
- CGGeneric(" = "),
- conversion,
- CGGeneric(";"),
- ]
- result.append(CGList(newDecl))
- else:
- result.append(conversion)
-
- # Add an empty CGGeneric to get an extra newline after the argument
- # conversion.
- result.append(CGGeneric(""))
-
- if needsRooting:
- rootBody = "let %s = %s.root();" % (declName, declName)
- result.append(CGGeneric(rootBody))
- result.append(CGGeneric(""))
-
- return result;
-
-def convertConstIDLValueToJSVal(value):
- if isinstance(value, IDLNullValue):
- return "NullVal"
- tag = value.type.tag()
- if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
- IDLType.Tags.uint16, IDLType.Tags.int32]:
- return "IntVal(%s)" % (value.value)
- if tag == IDLType.Tags.uint32:
- return "UintVal(%s)" % (value.value)
- if tag in [IDLType.Tags.int64, IDLType.Tags.uint64]:
- return "DoubleVal(%s)" % (value.value)
- if tag == IDLType.Tags.bool:
- return "BoolVal(true)" if value.value else "BoolVal(false)"
- if tag in [IDLType.Tags.float, IDLType.Tags.double]:
- return "DoubleVal(%s)" % (value.value)
- raise TypeError("Const value of unhandled type: " + value.type)
-
-class CGArgumentConverter(CGThing):
- """
- A class that takes an IDL argument object, its index in the
- argument list, and the argv and argc strings and generates code to
- unwrap the argument to the right native type.
- """
- def __init__(self, argument, index, argv, argc, descriptorProvider,
- invalidEnumValueFatal=True):
- CGThing.__init__(self)
- assert(not argument.defaultValue or argument.optional)
-
- replacer = {
- "index": index,
- "argc": argc,
- "argv": argv
- }
- condition = string.Template("${index} < ${argc}").substitute(replacer)
-
- replacementVariables = {
- "val": string.Template("(*${argv}.offset(${index}))").substitute(replacer),
- }
-
- template, default, declType, needsRooting = getJSToNativeConversionTemplate(
- argument.type,
- descriptorProvider,
- invalidEnumValueFatal=invalidEnumValueFatal,
- defaultValue=argument.defaultValue,
- treatNullAs=argument.treatNullAs,
- isEnforceRange=argument.enforceRange,
- isClamp=argument.clamp,
- isMember="Variadic" if argument.variadic else False,
- allowTreatNonObjectAsNull=argument.allowTreatNonCallableAsNull())
-
- if not argument.variadic:
- if argument.optional:
- if argument.defaultValue:
- assert default
- template = CGIfElseWrapper(condition,
- CGGeneric(template),
- CGGeneric(default)).define()
- else:
- assert not default
- declType = CGWrapper(declType, pre="Option<", post=">")
- template = CGIfElseWrapper(condition,
- CGGeneric("Some(%s)" % template),
- CGGeneric("None")).define()
- else:
- assert not default
-
- self.converter = instantiateJSToNativeConversionTemplate(
- template, replacementVariables, declType, "arg%d" % index,
- needsRooting)
- else:
- assert argument.optional
- variadicConversion = {
- "val": string.Template("(*${argv}.offset(variadicArg as int))").substitute(replacer),
- }
- innerConverter = instantiateJSToNativeConversionTemplate(
- template, variadicConversion, declType, "slot",
- needsRooting)
-
- seqType = CGTemplatedType("Vec", declType)
- variadicConversion = string.Template(
- "{\n"
- " let mut vector: ${seqType} = Vec::with_capacity((${argc} - ${index}) as uint);\n"
- " for variadicArg in range(${index}, ${argc}) {\n"
- "${inner}\n"
- " vector.push(slot);\n"
- " }\n"
- " vector\n"
- "}"
- ).substitute({
- "index": index,
- "argc": argc,
- "seqType": seqType.define(),
- "inner": CGIndenter(innerConverter, 4).define(),
- })
-
- self.converter = instantiateJSToNativeConversionTemplate(
- variadicConversion, replacementVariables, seqType, "arg%d" % index,
- False)
-
- def define(self):
- return self.converter.define()
-
-
-def wrapForType(jsvalRef, result='result', successCode='return 1;'):
- """
- Reflect a Rust value into JS.
-
- * 'jsvalRef': a Rust reference to the JSVal in which to store the result
- of the conversion;
- * 'result': the name of the variable in which the Rust value is stored;
- * 'successCode': the code to run once we have done the conversion.
- """
- return "%s = (%s).to_jsval(cx);\n%s" % (jsvalRef, result, successCode)
-
-
-def typeNeedsCx(type, retVal=False):
- if type is None:
- return False
- if type.nullable():
- type = type.inner
- if type.isSequence() or type.isArray():
- type = type.inner
- if type.isUnion():
- return any(typeNeedsCx(t) for t in type.unroll().flatMemberTypes)
- if retVal and type.isSpiderMonkeyInterface():
- return True
- return type.isAny() or type.isObject()
-
-def typeRetValNeedsRooting(type):
- if type is None:
- return False
- if type.nullable():
- type = type.inner
- return type.isGeckoInterface() and not type.isCallback() and not type.isCallbackInterface()
-
-def memberIsCreator(member):
- return member.getExtendedAttribute("Creator") is not None
-
-# Returns a CGThing containing the type of the return value.
-def getRetvalDeclarationForType(returnType, descriptorProvider):
- if returnType is None or returnType.isVoid():
- # Nothing to declare
- return CGGeneric("()")
- if returnType.isPrimitive() and returnType.tag() in builtinNames:
- result = CGGeneric(builtinNames[returnType.tag()])
- if returnType.nullable():
- result = CGWrapper(result, pre="Option<", post=">")
- return result
- if returnType.isDOMString():
- result = CGGeneric("DOMString")
- if returnType.nullable():
- result = CGWrapper(result, pre="Option<", post=">")
- return result
- if returnType.isByteString():
- result = CGGeneric("ByteString")
- if returnType.nullable():
- result = CGWrapper(result, pre="Option<", post=">")
- return result
- if returnType.isEnum():
- result = CGGeneric(returnType.unroll().inner.identifier.name)
- if returnType.nullable():
- result = CGWrapper(result, pre="Option<", post=">")
- return result
- if returnType.isGeckoInterface():
- descriptor = descriptorProvider.getDescriptor(
- returnType.unroll().inner.identifier.name)
- result = CGGeneric(descriptor.returnType)
- if returnType.nullable():
- result = CGWrapper(result, pre="Option<", post=">")
- return result
- if returnType.isCallback():
- result = CGGeneric('%s::%s' % (returnType.unroll().module(),
- returnType.unroll().identifier.name))
- if returnType.nullable():
- result = CGWrapper(result, pre="Option<", post=">")
- return result
- if returnType.isUnion():
- result = CGGeneric('%s::%s' % (returnType.unroll().name, returnType.unroll().name))
- if returnType.nullable():
- result = CGWrapper(result, pre="Option<", post=">")
- return result
- if returnType.isAny():
- return CGGeneric("JSVal")
- if returnType.isObject() or returnType.isSpiderMonkeyInterface():
- return CGGeneric("*mut JSObject")
- if returnType.isSequence():
- raise TypeError("We don't support sequence return values")
-
- raise TypeError("Don't know how to declare return value for %s" %
- returnType)
-
-class PropertyDefiner:
- """
- A common superclass for defining things on prototype objects.
-
- Subclasses should implement generateArray to generate the actual arrays of
- things we're defining. They should also set self.regular to the list of
- things exposed to web pages.
- """
- def __init__(self, descriptor, name):
- self.descriptor = descriptor
- self.name = name
-
- def variableName(self):
- return "s" + self.name
-
- def length(self):
- return len(self.regular)
-
- def __str__(self):
- # We only need to generate id arrays for things that will end
- # up used via ResolveProperty or EnumerateProperties.
- return self.generateArray(self.regular, self.variableName())
-
- def generatePrefableArray(self, array, name, specTemplate, specTerminator,
- specType, getDataTuple):
- """
- This method generates our various arrays.
-
- array is an array of interface members as passed to generateArray
-
- name is the name as passed to generateArray
-
- specTemplate is a template for each entry of the spec array
-
- specTerminator is a terminator for the spec array (inserted at the end
- of the array), or None
-
- specType is the actual typename of our spec
-
- getDataTuple is a callback function that takes an array entry and
- returns a tuple suitable for substitution into specTemplate.
- """
-
- assert(len(array) is not 0)
- specs = []
-
- for member in array:
- specs.append(specTemplate % getDataTuple(member))
- if specTerminator:
- specs.append(specTerminator)
-
- return (("static %s: &'static [%s] = &[\n" +
- ",\n".join(specs) + "\n" +
- "];\n\n") % (name, specType))
-
-# The length of a method is the maximum of the lengths of the
-# argument lists of all its overloads.
-def methodLength(method):
- signatures = method.signatures()
- return max([len(arguments) for (retType, arguments) in signatures])
-
-class MethodDefiner(PropertyDefiner):
- """
- A class for defining methods on a prototype object.
- """
- def __init__(self, descriptor, name, static):
- PropertyDefiner.__init__(self, descriptor, name)
-
- # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822
- # We should be able to check for special operations without an
- # identifier. For now we check if the name starts with __
- methods = [m for m in descriptor.interface.members if
- m.isMethod() and m.isStatic() == static and
- not m.isIdentifierLess()]
- self.regular = [{"name": m.identifier.name,
- "methodInfo": not m.isStatic(),
- "length": methodLength(m),
- "flags": "JSPROP_ENUMERATE" }
- for m in methods]
-
- # FIXME Check for an existing iterator on the interface first.
- if any(m.isGetter() and m.isIndexed() for m in methods):
- self.regular.append({"name": 'iterator',
- "methodInfo": False,
- "nativeName": "JS_ArrayIterator",
- "length": 0,
- "flags": "JSPROP_ENUMERATE" })
-
- def generateArray(self, array, name):
- if len(array) == 0:
- return ""
-
- def specData(m):
- if m.get("methodInfo", True):
- jitinfo = ("&%s_methodinfo" % m["name"])
- accessor = "genericMethod"
- else:
- jitinfo = "0 as *const JSJitInfo"
- accessor = m.get("nativeName", m["name"])
- return (m["name"], accessor, jitinfo, m["length"], m["flags"])
-
- def stringDecl(m):
- return "static %s_name: [u8, ..%i] = %s;\n" % (m["name"], len(m["name"]) + 1,
- str_to_const_array(m["name"]))
-
- decls = ''.join([stringDecl(m) for m in array])
- return decls + self.generatePrefableArray(
- array, name,
- ' JSFunctionSpec {name: &%s_name as *const u8 as *const libc::c_char, call: JSNativeWrapper {op: Some(%s), info: %s}, nargs: %s, flags: %s as u16, selfHostedName: 0 as *const libc::c_char }',
- ' JSFunctionSpec {name: 0 as *const libc::c_char, call: JSNativeWrapper {op: None, info: 0 as *const JSJitInfo}, nargs: 0, flags: 0, selfHostedName: 0 as *const libc::c_char }',
- 'JSFunctionSpec',
- specData)
-
-class AttrDefiner(PropertyDefiner):
- def __init__(self, descriptor, name, static):
- PropertyDefiner.__init__(self, descriptor, name)
- self.name = name
- self.regular = [
- m
- for m in descriptor.interface.members
- if m.isAttr() and m.isStatic() == static
- ]
- self.static = static
-
- def generateArray(self, array, name):
- if len(array) == 0:
- return ""
-
- def flags(attr):
- return "JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS"
-
- def getter(attr):
- if self.static:
- accessor = 'get_' + attr.identifier.name
- jitinfo = "0"
- else:
- if attr.hasLenientThis():
- accessor = "genericLenientGetter"
- else:
- accessor = "genericGetter"
- jitinfo = "&%s_getterinfo" % attr.identifier.name
-
- return ("JSPropertyOpWrapper {op: Some(%(native)s), info: %(info)s as *const JSJitInfo}"
- % {"info" : jitinfo,
- "native" : accessor})
-
- def setter(attr):
- if attr.readonly:
- return "JSStrictPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo}"
-
- if self.static:
- accessor = 'set_' + attr.identifier.name
- jitinfo = "0"
- else:
- if attr.hasLenientThis():
- accessor = "genericLenientSetter"
- else:
- accessor = "genericSetter"
- jitinfo = "&%s_setterinfo" % attr.identifier.name
-
- return ("JSStrictPropertyOpWrapper {op: Some(%(native)s), info: %(info)s as *const JSJitInfo}"
- % {"info" : jitinfo,
- "native" : accessor})
-
- def specData(attr):
- return (attr.identifier.name, flags(attr), getter(attr),
- setter(attr))
-
- def stringDecl(attr):
- name = attr.identifier.name
- return "static %s_name: [u8, ..%i] = %s;\n" % (name, len(name) + 1,
- str_to_const_array(name))
-
- decls = ''.join([stringDecl(m) for m in array])
-
- return decls + self.generatePrefableArray(
- array, name,
- ' JSPropertySpec { name: &%s_name as *const u8 as *const libc::c_char, tinyid: 0, flags: ((%s) & 0xFF) as u8, getter: %s, setter: %s }',
- ' JSPropertySpec { name: 0 as *const libc::c_char, tinyid: 0, flags: 0, getter: JSPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo}, setter: JSStrictPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo} }',
- 'JSPropertySpec',
- specData)
-
-class ConstDefiner(PropertyDefiner):
- """
- A class for definining constants on the interface object
- """
- def __init__(self, descriptor, name):
- PropertyDefiner.__init__(self, descriptor, name)
- self.name = name
- self.regular = [m for m in descriptor.interface.members if m.isConst()]
-
- def generateArray(self, array, name):
- if len(array) == 0:
- return ""
-
- def specData(const):
- return (const.identifier.name,
- convertConstIDLValueToJSVal(const.value))
-
- def stringDecl(const):
- name = const.identifier.name
- return "static %s_name: &'static [u8] = &%s;\n" % (name, str_to_const_array(name))
-
- decls = ''.join([stringDecl(m) for m in array])
-
- return decls + self.generatePrefableArray(
- array, name,
- ' ConstantSpec { name: %s_name, value: %s }',
- None,
- 'ConstantSpec',
- specData)
-
-# We'll want to insert the indent at the beginnings of lines, but we
-# don't want to indent empty lines. So only indent lines that have a
-# non-newline character on them.
-lineStartDetector = re.compile("^(?=[^\n])", re.MULTILINE)
-class CGIndenter(CGThing):
- """
- A class that takes another CGThing and generates code that indents that
- CGThing by some number of spaces. The default indent is two spaces.
- """
- def __init__(self, child, indentLevel=2):
- CGThing.__init__(self)
- self.child = child
- self.indent = " " * indentLevel
-
- def define(self):
- defn = self.child.define()
- if defn is not "":
- return re.sub(lineStartDetector, self.indent, defn)
- else:
- return defn
-
-class CGWrapper(CGThing):
- """
- Generic CGThing that wraps other CGThings with pre and post text.
- """
- def __init__(self, child, pre="", post="", reindent=False):
- CGThing.__init__(self)
- self.child = child
- self.pre = pre
- self.post = post
- self.reindent = reindent
-
- def define(self):
- defn = self.child.define()
- if self.reindent:
- # We don't use lineStartDetector because we don't want to
- # insert whitespace at the beginning of our _first_ line.
- defn = stripTrailingWhitespace(
- defn.replace("\n", "\n" + (" " * len(self.pre))))
- return self.pre + defn + self.post
-
-class CGImports(CGWrapper):
- """
- Generates the appropriate import/use statements.
- """
- def __init__(self, child, descriptors, imports):
- """
- Adds a set of imports.
- """
- ignored_warnings = [
- # Allow unreachable_code because we use 'break' in a way that
- # sometimes produces two 'break's in a row. See for example
- # CallbackMember.getArgConversions.
- 'unreachable_code',
- 'non_camel_case_types',
- 'non_uppercase_statics',
- 'unnecessary_parens',
- 'unused_imports',
- 'unused_variable',
- 'unused_unsafe',
- 'unused_mut',
- 'dead_assignment',
- 'dead_code',
- ]
-
- statements = ['#![allow(%s)]' % ','.join(ignored_warnings)]
- statements.extend('use %s;' % i for i in sorted(imports))
-
- CGWrapper.__init__(self, child,
- pre='\n'.join(statements) + '\n\n')
-
- @staticmethod
- def getDeclarationFilename(decl):
- # Use our local version of the header, not the exported one, so that
- # test bindings, which don't export, will work correctly.
- basename = os.path.basename(decl.filename())
- return basename.replace('.webidl', 'Binding.rs')
-
-class CGIfWrapper(CGWrapper):
- def __init__(self, child, condition):
- pre = CGWrapper(CGGeneric(condition), pre="if ", post=" {\n",
- reindent=True)
- CGWrapper.__init__(self, CGIndenter(child), pre=pre.define(),
- post="\n}")
-
-class CGTemplatedType(CGWrapper):
- def __init__(self, templateName, child):
- CGWrapper.__init__(self, child, pre=templateName + "<", post=">")
-
-class CGNamespace(CGWrapper):
- def __init__(self, namespace, child, public=False):
- pre = "%smod %s {\n" % ("pub " if public else "", namespace)
- post = "} // mod %s\n" % namespace
- CGWrapper.__init__(self, child, pre=pre, post=post)
-
- @staticmethod
- def build(namespaces, child, public=False):
- """
- Static helper method to build multiple wrapped namespaces.
- """
- if not namespaces:
- return child
- inner = CGNamespace.build(namespaces[1:], child, public=public)
- return CGNamespace(namespaces[0], inner, public=public)
-
-def DOMClass(descriptor):
- protoList = ['PrototypeList::id::' + proto for proto in descriptor.prototypeChain]
- # Pad out the list to the right length with IDCount so we
- # guarantee that all the lists are the same length. IDCount
- # is never the ID of any prototype, so it's safe to use as
- # padding.
- protoList.extend(['PrototypeList::id::IDCount'] * (descriptor.config.maxProtoChainLength - len(protoList)))
- prototypeChainString = ', '.join(protoList)
- return """DOMClass {
- interface_chain: [ %s ],
- native_hooks: &sNativePropertyHooks,
-}""" % prototypeChainString
-
-class CGDOMJSClass(CGThing):
- """
- Generate a DOMJSClass for a given descriptor
- """
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
-
- def define(self):
- traceHook = "Some(%s)" % TRACE_HOOK_NAME
- if self.descriptor.isGlobal():
- flags = "JSCLASS_IS_GLOBAL | JSCLASS_DOM_GLOBAL"
- slots = "JSCLASS_GLOBAL_SLOT_COUNT + 1"
- else:
- flags = "0"
- slots = "1"
- return """
-static Class_name: [u8, ..%i] = %s;
-static Class: DOMJSClass = DOMJSClass {
- base: js::Class {
- name: &Class_name as *const u8 as *const libc::c_char,
- flags: JSCLASS_IS_DOMJSCLASS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT as uint), //JSCLASS_HAS_RESERVED_SLOTS(%s),
- addProperty: Some(JS_PropertyStub),
- delProperty: Some(JS_PropertyStub),
- getProperty: Some(JS_PropertyStub),
- setProperty: Some(JS_StrictPropertyStub),
- enumerate: Some(JS_EnumerateStub),
- resolve: Some(JS_ResolveStub),
- convert: Some(JS_ConvertStub),
- finalize: Some(%s),
- checkAccess: None,
- call: None,
- hasInstance: None,
- construct: None,
- trace: %s,
-
- ext: js::ClassExtension {
- equality: 0 as *const u8,
- outerObject: %s,
- innerObject: None,
- iteratorObject: 0 as *const u8,
- unused: 0 as *const u8,
- isWrappedNative: 0 as *const u8,
- },
-
- ops: js::ObjectOps {
- lookupGeneric: 0 as *const u8,
- lookupProperty: 0 as *const u8,
- lookupElement: 0 as *const u8,
- lookupSpecial: 0 as *const u8,
- defineGeneric: 0 as *const u8,
- defineProperty: 0 as *const u8,
- defineElement: 0 as *const u8,
- defineSpecial: 0 as *const u8,
- getGeneric: 0 as *const u8,
- getProperty: 0 as *const u8,
- getElement: 0 as *const u8,
- getElementIfPresent: 0 as *const u8,
- getSpecial: 0 as *const u8,
- setGeneric: 0 as *const u8,
- setProperty: 0 as *const u8,
- setElement: 0 as *const u8,
- setSpecial: 0 as *const u8,
- getGenericAttributes: 0 as *const u8,
- getPropertyAttributes: 0 as *const u8,
- getElementAttributes: 0 as *const u8,
- getSpecialAttributes: 0 as *const u8,
- setGenericAttributes: 0 as *const u8,
- setPropertyAttributes: 0 as *const u8,
- setElementAttributes: 0 as *const u8,
- setSpecialAttributes: 0 as *const u8,
- deleteProperty: 0 as *const u8,
- deleteElement: 0 as *const u8,
- deleteSpecial: 0 as *const u8,
-
- enumerate: 0 as *const u8,
- typeOf: 0 as *const u8,
- thisObject: %s,
- clear: 0 as *const u8,
- },
- },
- dom_class: %s
-};
-""" % (len(self.descriptor.interface.identifier.name) + 1,
- str_to_const_array(self.descriptor.interface.identifier.name),
- flags, slots, slots,
- FINALIZE_HOOK_NAME, traceHook,
- self.descriptor.outerObjectHook,
- self.descriptor.outerObjectHook,
- CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
-
-def str_to_const_array(s):
- return "[" + (", ".join(map(lambda x: "'" + x + "' as u8", list(s)) + ['0 as u8'])) + "]"
-
-class CGPrototypeJSClass(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
-
- def define(self):
- return """
-static PrototypeClassName__: [u8, ..%s] = %s;
-static PrototypeClass: JSClass = JSClass {
- name: &PrototypeClassName__ as *const u8 as *const libc::c_char,
- flags: (1 & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT as uint, //JSCLASS_HAS_RESERVED_SLOTS(1)
- addProperty: Some(JS_PropertyStub),
- delProperty: Some(JS_PropertyStub),
- getProperty: Some(JS_PropertyStub),
- setProperty: Some(JS_StrictPropertyStub),
- enumerate: Some(JS_EnumerateStub),
- resolve: Some(JS_ResolveStub),
- convert: Some(JS_ConvertStub),
- finalize: None,
- checkAccess: None,
- call: None,
- hasInstance: None,
- construct: None,
- trace: None,
- reserved: [0 as *mut libc::c_void, ..40]
-};
-""" % (len(self.descriptor.interface.identifier.name + "Prototype") + 1,
- str_to_const_array(self.descriptor.interface.identifier.name + "Prototype"))
-
-class CGInterfaceObjectJSClass(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
-
- def define(self):
- if True:
- return ""
- ctorname = "0 as *const u8" if not self.descriptor.interface.ctor() else CONSTRUCT_HOOK_NAME
- hasinstance = HASINSTANCE_HOOK_NAME
- return """
-static InterfaceObjectClass: JSClass = {
- %s, 0,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- 0 as *const u8,
- 0 as *const u8,
- %s,
- %s,
- %s,
- 0 as *const u8,
- JSCLASS_NO_INTERNAL_MEMBERS
-};
-""" % (str_to_const_array("Function"), ctorname, hasinstance, ctorname)
-
-class CGList(CGThing):
- """
- Generate code for a list of GCThings. Just concatenates them together, with
- an optional joiner string. "\n" is a common joiner.
- """
- def __init__(self, children, joiner=""):
- CGThing.__init__(self)
- self.children = children
- self.joiner = joiner
- def append(self, child):
- self.children.append(child)
- def prepend(self, child):
- self.children.insert(0, child)
- def join(self, generator):
- return self.joiner.join(filter(lambda s: len(s) > 0, (child for child in generator)))
-
- def define(self):
- return self.join(child.define() for child in self.children if child is not None)
-
-
-class CGIfElseWrapper(CGList):
- def __init__(self, condition, ifTrue, ifFalse):
- kids = [ CGIfWrapper(ifTrue, condition),
- CGWrapper(CGIndenter(ifFalse), pre=" else {\n", post="\n}") ]
- CGList.__init__(self, kids)
-
-
-class CGGeneric(CGThing):
- """
- A class that spits out a fixed string into the codegen. Can spit out a
- separate string for the declaration too.
- """
- def __init__(self, text):
- self.text = text
-
- def define(self):
- return self.text
-
-class CGCallbackTempRoot(CGGeneric):
- def __init__(self, name):
- val = "%s::new(tempRoot)" % name
- define = """{
- let tempRoot = ${val}.to_object();
- %s
-}""" % val
- CGGeneric.__init__(self, define)
-
-
-def getAllTypes(descriptors, dictionaries, callbacks):
- """
- Generate all the types we're dealing with. For each type, a tuple
- containing type, descriptor, dictionary is yielded. The
- descriptor and dictionary can be None if the type does not come
- from a descriptor or dictionary; they will never both be non-None.
- """
- for d in descriptors:
- for t in getTypesFromDescriptor(d):
- yield (t, d, None)
- for dictionary in dictionaries:
- for t in getTypesFromDictionary(dictionary):
- yield (t, None, dictionary)
- for callback in callbacks:
- for t in getTypesFromCallback(callback):
- yield (t, None, None)
-
-def SortedTuples(l):
- """
- Sort a list of tuples based on the first item in the tuple
- """
- return sorted(l, key=operator.itemgetter(0))
-
-def SortedDictValues(d):
- """
- Returns a list of values from the dict sorted by key.
- """
- # Create a list of tuples containing key and value, sorted on key.
- d = SortedTuples(d.items())
- # We're only interested in the values.
- return (i[1] for i in d)
-
-def UnionTypes(descriptors, dictionaries, callbacks, config):
- """
- Returns a CGList containing CGUnionStructs for every union.
- """
-
- imports = [
- 'dom::bindings::utils::unwrap_jsmanaged',
- 'dom::bindings::codegen::PrototypeList',
- 'dom::bindings::conversions::FromJSValConvertible',
- 'dom::bindings::conversions::ToJSValConvertible',
- 'dom::bindings::conversions::Default',
- 'dom::bindings::error::throw_not_in_union',
- 'dom::bindings::js::JS',
- 'dom::types::*',
- 'js::jsapi::JSContext',
- 'js::jsval::JSVal',
- 'servo_util::str::DOMString',
- ]
-
- # Now find all the things we'll need as arguments and return values because
- # we need to wrap or unwrap them.
- unionStructs = dict()
- for (t, descriptor, dictionary) in getAllTypes(descriptors, dictionaries, callbacks):
- assert not descriptor or not dictionary
- t = t.unroll()
- if not t.isUnion():
- continue
- name = str(t)
- if not name in unionStructs:
- provider = descriptor or config.getDescriptorProvider()
- unionStructs[name] = CGNamespace(name,
- CGImports(CGList([
- CGUnionStruct(t, provider),
- CGUnionConversionStruct(t, provider)
- ]), [], imports),
- public=True)
-
- return CGList(SortedDictValues(unionStructs), "\n\n")
-
-
-class Argument():
- """
- A class for outputting the type and name of an argument
- """
- def __init__(self, argType, name, default=None, mutable=False):
- self.argType = argType
- self.name = name
- self.default = default
- self.mutable = mutable
- def declare(self):
- string = ('mut ' if self.mutable else '') + self.name + ((': ' + self.argType) if self.argType else '')
- #XXXjdm Support default arguments somehow :/
- #if self.default is not None:
- # string += " = " + self.default
- return string
- def define(self):
- return self.argType + ' ' + self.name
-
-class CGAbstractMethod(CGThing):
- """
- An abstract class for generating code for a method. Subclasses
- should override definition_body to create the actual code.
-
- descriptor is the descriptor for the interface the method is associated with
-
- name is the name of the method as a string
-
- returnType is the IDLType of the return value
-
- args is a list of Argument objects
-
- inline should be True to generate an inline method, whose body is
- part of the declaration.
-
- alwaysInline should be True to generate an inline method annotated with
- MOZ_ALWAYS_INLINE.
-
- If templateArgs is not None it should be a list of strings containing
- template arguments, and the function will be templatized using those
- arguments.
- """
- def __init__(self, descriptor, name, returnType, args, inline=False, alwaysInline=False, extern=False, pub=False, templateArgs=None, unsafe=True):
- CGThing.__init__(self)
- self.descriptor = descriptor
- self.name = name
- self.returnType = returnType
- self.args = args
- self.alwaysInline = alwaysInline
- self.extern = extern
- self.templateArgs = templateArgs
- self.pub = pub;
- self.unsafe = unsafe
- def _argstring(self):
- return ', '.join([a.declare() for a in self.args])
- def _template(self):
- if self.templateArgs is None:
- return ''
- return '<%s>\n' % ', '.join(self.templateArgs)
-
- def _decorators(self):
- decorators = []
- if self.alwaysInline:
- decorators.append('#[inline(always)]')
-
- if self.extern:
- decorators.append('extern')
-
- if self.pub:
- decorators.append('pub')
-
- if not decorators:
- return ''
- return ' '.join(decorators) + ' '
-
- def _returnType(self):
- return (" -> %s" % self.returnType) if self.returnType != "void" else ""
-
- def define(self):
- body = self.definition_body()
- if self.unsafe:
- body = CGWrapper(body, pre="unsafe {\n", post="\n}")
-
- return CGWrapper(CGIndenter(body),
- pre=self.definition_prologue(),
- post=self.definition_epilogue()).define()
-
- def definition_prologue(self):
- return "%sfn %s%s(%s)%s {\n" % (self._decorators(), self.name, self._template(),
- self._argstring(), self._returnType())
- def definition_epilogue(self):
- return "\n}\n"
- def definition_body(self):
- assert(False) # Override me!
-
-def CreateBindingJSObject(descriptor, parent=None):
- create = "let mut raw: JS<%s> = JS::from_raw(&*aObject);\n" % descriptor.concreteType
- if descriptor.proxy:
- assert not descriptor.isGlobal()
- create += """
-let handler = RegisterBindings::proxy_handlers[PrototypeList::proxies::%s as uint];
-let mut private = PrivateValue(squirrel_away_unique(aObject) as *const libc::c_void);
-let obj = with_compartment(aCx, proto, || {
- NewProxyObject(aCx, handler,
- &private,
- proto, %s,
- ptr::mut_null(), ptr::mut_null())
-});
-assert!(obj.is_not_null());
-
-""" % (descriptor.name, parent)
- else:
- if descriptor.isGlobal():
- create += "let obj = CreateDOMGlobal(aCx, &Class.base as *const js::Class as *const JSClass);\n"
- else:
- create += ("let obj = with_compartment(aCx, proto, || {\n"
- " JS_NewObject(aCx, &Class.base as *const js::Class as *const JSClass, &*proto, &*%s)\n"
- "});\n" % parent)
- create += """assert!(obj.is_not_null());
-
-JS_SetReservedSlot(obj, DOM_OBJECT_SLOT as u32,
- PrivateValue(squirrel_away_unique(aObject) as *const libc::c_void));
-"""
- return create
-
-class CGWrapMethod(CGAbstractMethod):
- """
- Class that generates the FooBinding::Wrap function for non-callback
- interfaces.
- """
- def __init__(self, descriptor):
- assert not descriptor.interface.isCallback()
- if not descriptor.isGlobal():
- args = [Argument('*mut JSContext', 'aCx'), Argument('&GlobalRef', 'aScope'),
- Argument("Box<%s>" % descriptor.concreteType, 'aObject', mutable=True)]
- else:
- args = [Argument('*mut JSContext', 'aCx'),
- Argument("Box<%s>" % descriptor.concreteType, 'aObject', mutable=True)]
- retval = 'Temporary<%s>' % descriptor.concreteType
- CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args, pub=True)
-
- def definition_body(self):
- if not self.descriptor.isGlobal():
- return CGGeneric("""\
-let scope = aScope.reflector().get_jsobject();
-assert!(scope.is_not_null());
-assert!(((*JS_GetClass(scope)).flags & JSCLASS_IS_GLOBAL) != 0);
-
-let proto = with_compartment(aCx, scope, || GetProtoObject(aCx, scope, scope));
-assert!(proto.is_not_null());
-
-%s
-
-raw.reflector().set_jsobject(obj);
-
-Temporary::new(raw)""" % CreateBindingJSObject(self.descriptor, "scope"))
- else:
- return CGGeneric("""\
-%s
-with_compartment(aCx, obj, || {
- let proto = GetProtoObject(aCx, obj, obj);
- JS_SetPrototype(aCx, obj, proto);
-
- raw.reflector().set_jsobject(obj);
-
- RegisterBindings::Register(aCx, obj);
-});
-
-Temporary::new(raw)""" % CreateBindingJSObject(self.descriptor))
-
-
-class CGIDLInterface(CGThing):
- """
- Class for codegen of an implementation of the IDLInterface trait.
- """
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
-
- def define(self):
- replacer = {
- 'type': self.descriptor.name,
- 'depth': self.descriptor.interface.inheritanceDepth(),
- }
- return string.Template("""
-impl IDLInterface for ${type} {
- fn get_prototype_id(_: Option<${type}>) -> PrototypeList::id::ID {
- PrototypeList::id::${type}
- }
- fn get_prototype_depth(_: Option<${type}>) -> uint {
- ${depth}
- }
-}
-""").substitute(replacer)
-
-
-class CGAbstractExternMethod(CGAbstractMethod):
- """
- Abstract base class for codegen of implementation-only (no
- declaration) static methods.
- """
- def __init__(self, descriptor, name, returnType, args):
- CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
- inline=False, extern=True)
-
-class PropertyArrays():
- def __init__(self, descriptor):
- self.staticMethods = MethodDefiner(descriptor, "StaticMethods",
- static=True)
- self.staticAttrs = AttrDefiner(descriptor, "StaticAttributes",
- static=True)
- self.methods = MethodDefiner(descriptor, "Methods", static=False)
- self.attrs = AttrDefiner(descriptor, "Attributes", static=False)
- self.consts = ConstDefiner(descriptor, "Constants")
- pass
-
- @staticmethod
- def arrayNames():
- return [ "staticMethods", "staticAttrs", "methods", "attrs", "consts" ]
-
- def variableNames(self):
- names = {}
- for array in self.arrayNames():
- names[array] = getattr(self, array).variableName()
- return names
- def __str__(self):
- define = ""
- for array in self.arrayNames():
- define += str(getattr(self, array))
- return define
-
-
-class CGNativeProperties(CGThing):
- def __init__(self, descriptor, properties):
- CGThing.__init__(self)
- self.properties = properties
-
- def define(self):
- def getField(array):
- propertyArray = getattr(self.properties, array)
- if propertyArray.length() > 0:
- value = "Some(%s)" % propertyArray.variableName()
- else:
- value = "None"
-
- return CGGeneric(string.Template('${name}: ${value},').substitute({
- 'name': array,
- 'value': value,
- }))
-
- nativeProps = CGList([getField(array) for array in self.properties.arrayNames()], '\n')
- return CGWrapper(CGIndenter(nativeProps),
- pre="static sNativeProperties: NativeProperties = NativeProperties {\n",
- post="\n};\n").define()
-
-
-class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
- """
- Generate the CreateInterfaceObjects method for an interface descriptor.
-
- properties should be a PropertyArrays instance.
- """
- def __init__(self, descriptor, properties):
- assert not descriptor.interface.isCallback()
- args = [Argument('*mut JSContext', 'aCx'), Argument('*mut JSObject', 'aGlobal'),
- Argument('*mut JSObject', 'aReceiver')]
- CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', '*mut JSObject', args)
- self.properties = properties
- def definition_body(self):
- protoChain = self.descriptor.prototypeChain
- if len(protoChain) == 1:
- getParentProto = "JS_GetObjectPrototype(aCx, aGlobal)"
- else:
- parentProtoName = self.descriptor.prototypeChain[-2]
- getParentProto = ("%s::GetProtoObject(aCx, aGlobal, aReceiver)" %
- toBindingNamespace(parentProtoName))
-
- getParentProto = ("let parentProto: *mut JSObject = %s;\n"
- "assert!(parentProto.is_not_null());\n") % getParentProto
-
- if self.descriptor.concrete:
- if self.descriptor.proxy:
- domClass = "&Class"
- else:
- domClass = "&Class.dom_class"
- else:
- domClass = "ptr::null()"
-
- if self.descriptor.interface.hasInterfaceObject():
- if self.descriptor.interface.ctor():
- constructHook = CONSTRUCT_HOOK_NAME
- constructArgs = methodLength(self.descriptor.interface.ctor())
- else:
- constructHook = "ThrowingConstructor"
- constructArgs = 0
-
- constructor = 'Some((%s, "%s", %d))' % (
- constructHook, self.descriptor.interface.identifier.name,
- constructArgs)
- else:
- constructor = 'None'
-
- call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto,
- &PrototypeClass, %s,
- %s,
- &sNativeProperties);""" % (constructor, domClass)
-
- return CGList([
- CGGeneric(getParentProto),
- CGGeneric(call % self.properties.variableNames())
- ], "\n")
-
-class CGGetPerInterfaceObject(CGAbstractMethod):
- """
- A method for getting a per-interface object (a prototype object or interface
- constructor object).
- """
- def __init__(self, descriptor, name, idPrefix="", pub=False):
- args = [Argument('*mut JSContext', 'aCx'), Argument('*mut JSObject', 'aGlobal'),
- Argument('*mut JSObject', 'aReceiver')]
- CGAbstractMethod.__init__(self, descriptor, name,
- '*mut JSObject', args, pub=pub)
- self.id = idPrefix + "id::" + self.descriptor.name
- def definition_body(self):
- return CGGeneric("""
-
-/* aGlobal and aReceiver are usually the same, but they can be different
- too. For example a sandbox often has an xray wrapper for a window as the
- prototype of the sandbox's global. In that case aReceiver is the xray
- wrapper and aGlobal is the sandbox's global.
- */
-
-assert!(((*JS_GetClass(aGlobal)).flags & JSCLASS_DOM_GLOBAL) != 0);
-
-/* Check to see whether the interface objects are already installed */
-let protoOrIfaceArray = GetProtoOrIfaceArray(aGlobal);
-let cachedObject: *mut JSObject = *protoOrIfaceArray.offset(%s as int);
-if cachedObject.is_null() {
- let tmp: *mut JSObject = CreateInterfaceObjects(aCx, aGlobal, aReceiver);
- assert!(tmp.is_not_null());
- *protoOrIfaceArray.offset(%s as int) = tmp;
- tmp
-} else {
- cachedObject
-}""" % (self.id, self.id))
-
-class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
- """
- A method for getting the interface prototype object.
- """
- def __init__(self, descriptor):
- CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
- "PrototypeList::", pub=True)
- def definition_body(self):
- return CGList([
- CGGeneric("""\
-/* Get the interface prototype object for this class. This will create the
- object as needed. */"""),
- CGGetPerInterfaceObject.definition_body(self),
- ])
-
-class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
- """
- A method for getting the interface constructor object.
- """
- def __init__(self, descriptor):
- CGGetPerInterfaceObject.__init__(self, descriptor, "GetConstructorObject",
- "constructors::")
- def definition_body(self):
- return CGList([
- CGGeneric("""\
-/* Get the interface object for this class. This will create the object as
- needed. */"""),
- CGGetPerInterfaceObject.definition_body(self),
- ])
-
-
-class CGDefineProxyHandler(CGAbstractMethod):
- """
- A method to create and cache the proxy trap for a given interface.
- """
- def __init__(self, descriptor):
- assert descriptor.proxy
- CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler', '*const libc::c_void', [], pub=True)
-
- def define(self):
- return CGAbstractMethod.define(self)
-
- def definition_body(self):
- body = """\
-let traps = ProxyTraps {
- getPropertyDescriptor: Some(getPropertyDescriptor),
- getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
- defineProperty: Some(defineProperty),
- getOwnPropertyNames: ptr::null(),
- delete_: Some(delete_),
- enumerate: ptr::null(),
-
- has: None,
- hasOwn: Some(hasOwn),
- get: Some(get),
- set: None,
- keys: ptr::null(),
- iterate: None,
-
- call: None,
- construct: None,
- nativeCall: ptr::null(),
- hasInstance: None,
- typeOf: None,
- objectClassIs: None,
- obj_toString: Some(obj_toString),
- fun_toString: None,
- //regexp_toShared: ptr::null(),
- defaultValue: None,
- iteratorNext: None,
- finalize: Some(%s),
- getElementIfPresent: None,
- getPrototypeOf: None,
- trace: Some(%s)
-};
-
-CreateProxyHandler(&traps, &Class as *const _ as *const _)
-""" % (FINALIZE_HOOK_NAME,
- TRACE_HOOK_NAME)
- return CGGeneric(body)
-
-
-
-class CGDefineDOMInterfaceMethod(CGAbstractMethod):
- """
- A method for resolve hooks to try to lazily define the interface object for
- a given interface.
- """
- def __init__(self, descriptor):
- assert descriptor.interface.hasInterfaceObject()
- args = [
- Argument('*mut JSContext', 'cx'),
- Argument('*mut JSObject', 'global'),
- ]
- CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'void', args, pub=True)
-
- def define(self):
- return CGAbstractMethod.define(self)
-
- def definition_body(self):
- return CGGeneric("""\
-assert!(global.is_not_null());
-assert!(GetProtoObject(cx, global, global).is_not_null());""")
-
-def needCx(returnType, arguments, considerTypes):
- return (considerTypes and
- (typeNeedsCx(returnType, True) or
- any(typeNeedsCx(a.type) for a in arguments)))
-
-class CGCallGenerator(CGThing):
- """
- A class to generate an actual call to a C++ object. Assumes that the C++
- object is stored in a variable whose name is given by the |object| argument.
-
- errorResult should be a string for the value to return in case of an
- exception from the native code, or None if no error reporting is needed.
- """
- def __init__(self, errorResult, arguments, argsPre, returnType,
- extendedAttributes, descriptorProvider, nativeMethodName,
- static, object="this"):
- CGThing.__init__(self)
-
- assert errorResult is None or isinstance(errorResult, str)
-
- isFallible = errorResult is not None
-
- result = getRetvalDeclarationForType(returnType, descriptorProvider)
- if isFallible:
- result = CGWrapper(result, pre="Result<", post=", Error>")
-
- args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
- for (a, name) in arguments:
- #XXXjdm Perhaps we should pass all nontrivial types by borrowed pointer
- if a.type.isGeckoInterface():
- if not (a.type.nullable() or a.optional):
- name = "&" + name
- elif a.type.isDictionary():
- name = "&" + name
- args.append(CGGeneric(name))
-
- needsCx = needCx(returnType, (a for (a, _) in arguments), True)
-
- if not "cx" in argsPre and needsCx:
- args.prepend(CGGeneric("cx"))
-
- # Build up our actual call
- self.cgRoot = CGList([], "\n")
-
- call = CGGeneric(nativeMethodName)
- if static:
- call = CGWrapper(call, pre="%s::" % descriptorProvider.interface.identifier.name)
- else:
- call = CGWrapper(call, pre="(*%s)." % object)
- call = CGList([call, CGWrapper(args, pre="(", post=")")])
-
- self.cgRoot.append(CGList([
- CGGeneric("let result: "),
- result,
- CGGeneric(" = "),
- call,
- CGGeneric(";"),
- ]))
-
- if isFallible:
- if static:
- glob = ""
- else:
- glob = " let global = global_object_for_js_object(this.reflector().get_jsobject());\n"\
- " let global = global.root();\n"
-
- self.cgRoot.append(CGGeneric(
- "let result = match result {\n"
- " Ok(result) => result,\n"
- " Err(e) => {\n"
- "%s"
- " throw_dom_exception(cx, &global.root_ref(), e);\n"
- " return%s;\n"
- " },\n"
- "};\n" % (glob, errorResult)))
-
- if typeRetValNeedsRooting(returnType):
- self.cgRoot.append(CGGeneric("let result = result.root();"))
-
- def define(self):
- return self.cgRoot.define()
-
-class MethodNotCreatorError(Exception):
- def __init__(self, typename):
- self.typename = typename
-
-class CGPerSignatureCall(CGThing):
- """
- This class handles the guts of generating code for a particular
- call signature. A call signature consists of four things:
-
- 1) A return type, which can be None to indicate that there is no
- actual return value (e.g. this is an attribute setter) or an
- IDLType if there's an IDL type involved (including |void|).
- 2) An argument list, which is allowed to be empty.
- 3) A name of a native method to call.
- 4) Whether or not this method is static.
-
- We also need to know whether this is a method or a getter/setter
- to do error reporting correctly.
-
- The idlNode parameter can be either a method or an attr. We can query
- |idlNode.identifier| in both cases, so we can be agnostic between the two.
- """
- # XXXbz For now each entry in the argument list is either an
- # IDLArgument or a FakeArgument, but longer-term we may want to
- # have ways of flagging things like JSContext* or optional_argc in
- # there.
-
- def __init__(self, returnType, argsPre, arguments, nativeMethodName, static,
- descriptor, idlNode, argConversionStartsAt=0,
- getter=False, setter=False):
- CGThing.__init__(self)
- self.returnType = returnType
- self.descriptor = descriptor
- self.idlNode = idlNode
- self.extendedAttributes = descriptor.getExtendedAttributes(idlNode,
- getter=getter,
- setter=setter)
- self.argsPre = argsPre
- self.arguments = arguments
- self.argCount = len(arguments)
- if self.argCount > argConversionStartsAt:
- # Insert our argv in there
- cgThings = [CGGeneric(self.getArgvDecl())]
- else:
- cgThings = []
- cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgv(),
- self.getArgc(), self.descriptor,
- invalidEnumValueFatal=not setter) for
- i in range(argConversionStartsAt, self.argCount)])
-
- cgThings.append(CGCallGenerator(
- ' false as JSBool' if self.isFallible() else None,
- self.getArguments(), self.argsPre, returnType,
- self.extendedAttributes, descriptor, nativeMethodName,
- static))
- self.cgRoot = CGList(cgThings, "\n")
-
- def getArgv(self):
- return "argv" if self.argCount > 0 else ""
- def getArgvDecl(self):
- return "\nlet argv = JS_ARGV(cx, vp);\n"
- def getArgc(self):
- return "argc"
- def getArguments(self):
- def process(arg, i):
- argVal = "arg" + str(i)
- if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback():
- argVal += ".root_ref()"
- return argVal
- return [(a, process(a, i)) for (i, a) in enumerate(self.arguments)]
-
- def isFallible(self):
- return not 'infallible' in self.extendedAttributes
-
- def wrap_return_value(self):
- return wrapForType('*vp')
-
- def define(self):
- return (self.cgRoot.define() + "\n" + self.wrap_return_value())
-
-class CGSwitch(CGList):
- """
- A class to generate code for a switch statement.
-
- Takes three constructor arguments: an expression, a list of cases,
- and an optional default.
-
- Each case is a CGCase. The default is a CGThing for the body of
- the default case, if any.
- """
- def __init__(self, expression, cases, default=None):
- CGList.__init__(self, [CGIndenter(c) for c in cases], "\n")
- self.prepend(CGWrapper(CGGeneric(expression),
- pre="match ", post=" {"));
- if default is not None:
- self.append(
- CGIndenter(
- CGWrapper(
- CGIndenter(default),
- pre="_ => {\n",
- post="\n}"
- )
- )
- )
-
- self.append(CGGeneric("}"))
-
-class CGCase(CGList):
- """
- A class to generate code for a case statement.
-
- Takes three constructor arguments: an expression, a CGThing for
- the body (allowed to be None if there is no body), and an optional
- argument (defaulting to False) for whether to fall through.
- """
- def __init__(self, expression, body, fallThrough=False):
- CGList.__init__(self, [], "\n")
- self.append(CGWrapper(CGGeneric(expression), post=" => {"))
- bodyList = CGList([body], "\n")
- if fallThrough:
- raise TypeError("fall through required but unsupported")
- #bodyList.append(CGGeneric('fail!("fall through unsupported"); /* Fall through */'))
- self.append(CGIndenter(bodyList));
- self.append(CGGeneric("}"))
-
-class CGGetterCall(CGPerSignatureCall):
- """
- A class to generate a native object getter call for a particular IDL
- getter.
- """
- def __init__(self, argsPre, returnType, nativeMethodName, descriptor, attr):
- CGPerSignatureCall.__init__(self, returnType, argsPre, [],
- nativeMethodName, attr.isStatic(), descriptor,
- attr, getter=True)
-
-class FakeArgument():
- """
- A class that quacks like an IDLArgument. This is used to make
- setters look like method calls or for special operations.
- """
- def __init__(self, type, interfaceMember, allowTreatNonObjectAsNull=False):
- self.type = type
- self.optional = False
- self.variadic = False
- self.defaultValue = None
- self._allowTreatNonObjectAsNull = allowTreatNonObjectAsNull
- self.treatNullAs = interfaceMember.treatNullAs
- self.enforceRange = False
- self.clamp = False
-
- def allowTreatNonCallableAsNull(self):
- return self._allowTreatNonObjectAsNull
-
-class CGSetterCall(CGPerSignatureCall):
- """
- A class to generate a native object setter call for a particular IDL
- setter.
- """
- def __init__(self, argsPre, argType, nativeMethodName, descriptor, attr):
- CGPerSignatureCall.__init__(self, None, argsPre,
- [FakeArgument(argType, attr, allowTreatNonObjectAsNull=True)],
- nativeMethodName, attr.isStatic(), descriptor, attr,
- setter=True)
- def wrap_return_value(self):
- # We have no return value
- return "\nreturn 1;"
- def getArgc(self):
- return "1"
- def getArgvDecl(self):
- # We just get our stuff from our last arg no matter what
- return ""
-
-class CGAbstractBindingMethod(CGAbstractExternMethod):
- """
- Common class to generate the JSNatives for all our methods, getters, and
- setters. This will generate the function declaration and unwrap the
- |this| object. Subclasses are expected to override the generate_code
- function to do the rest of the work. This function should return a
- CGThing which is already properly indented.
- """
- def __init__(self, descriptor, name, args, unwrapFailureCode=None):
- CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
-
- if unwrapFailureCode is None:
- self.unwrapFailureCode = (
- 'throw_type_error(cx, "\\"this\\" object does not '
- 'implement interface %s.");\n'
- 'return 0;' % descriptor.interface.identifier.name)
- else:
- self.unwrapFailureCode = unwrapFailureCode
-
- def definition_body(self):
- # Our descriptor might claim that we're not castable, simply because
- # we're someone's consequential interface. But for this-unwrapping, we
- # know that we're the real deal. So fake a descriptor here for
- # consumption by FailureFatalCastableObjectUnwrapper.
- unwrapThis = str(CastableObjectUnwrapper(
- FakeCastableDescriptor(self.descriptor),
- "obj", self.unwrapFailureCode))
- unwrapThis = CGGeneric(
- "let obj: *mut JSObject = JS_THIS_OBJECT(cx, vp as *mut JSVal);\n"
- "if obj.is_null() {\n"
- " return false as JSBool;\n"
- "}\n"
- "\n"
- "let this: JS<%s> = %s;\n" % (self.descriptor.concreteType, unwrapThis))
- return CGList([ unwrapThis, self.generate_code() ], "\n")
-
- def generate_code(self):
- assert(False) # Override me
-
-
-class CGAbstractStaticBindingMethod(CGAbstractMethod):
- """
- Common class to generate the JSNatives for all our static methods, getters
- and setters. This will generate the function declaration and unwrap the
- global object. Subclasses are expected to override the generate_code
- function to do the rest of the work. This function should return a
- CGThing which is already properly indented.
- """
- def __init__(self, descriptor, name):
- args = [
- Argument('*mut JSContext', 'cx'),
- Argument('libc::c_uint', 'argc'),
- Argument('*mut JSVal', 'vp'),
- ]
- CGAbstractMethod.__init__(self, descriptor, name, "JSBool", args, extern=True)
-
- def definition_body(self):
- return self.generate_code()
-
- def generate_code(self):
- assert False # Override me
-
-
-class CGGenericMethod(CGAbstractBindingMethod):
- """
- A class for generating the C++ code for an IDL method..
- """
- def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('libc::c_uint', 'argc'),
- Argument('*mut JSVal', 'vp')]
- CGAbstractBindingMethod.__init__(self, descriptor, 'genericMethod', args)
-
- def generate_code(self):
- return CGGeneric(
- "let _info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "return CallJitMethodOp(_info, cx, obj, this.unsafe_get() as *mut libc::c_void, argc, vp);")
-
-class CGSpecializedMethod(CGAbstractExternMethod):
- """
- A class for generating the C++ code for a specialized method that the JIT
- can call with lower overhead.
- """
- def __init__(self, descriptor, method):
- self.method = method
- name = method.identifier.name
- args = [Argument('*mut JSContext', 'cx'), Argument('JSHandleObject', '_obj'),
- Argument('*const %s' % descriptor.concreteType, 'this'),
- Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')]
- CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args)
-
- def definition_body(self):
- nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
- self.method)
- return CGWrapper(CGMethodCall([], nativeName, self.method.isStatic(),
- self.descriptor, self.method),
- pre="let this = JS::from_raw(this);\n"
- "let this = this.root();\n")
-
- @staticmethod
- def makeNativeName(descriptor, method):
- return MakeNativeName(method.identifier.name)
-
-class CGStaticMethod(CGAbstractStaticBindingMethod):
- """
- A class for generating the Rust code for an IDL static method.
- """
- def __init__(self, descriptor, method):
- self.method = method
- name = method.identifier.name
- CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
-
- def generate_code(self):
- nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
- self.method)
- return CGMethodCall([], nativeName, True, self.descriptor, self.method)
-
-
-class CGGenericGetter(CGAbstractBindingMethod):
- """
- A class for generating the C++ code for an IDL attribute getter.
- """
- def __init__(self, descriptor, lenientThis=False):
- args = [Argument('*mut JSContext', 'cx'), Argument('libc::c_uint', 'argc'),
- Argument('*mut JSVal', 'vp')]
- if lenientThis:
- name = "genericLenientGetter"
- unwrapFailureCode = (
- "MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
- "JS_SET_RVAL(cx, vp, JS::UndefinedValue());\n"
- "return true;")
- else:
- name = "genericGetter"
- unwrapFailureCode = None
- CGAbstractBindingMethod.__init__(self, descriptor, name, args,
- unwrapFailureCode)
-
- def generate_code(self):
- return CGGeneric(
- "let info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "return CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *mut libc::c_void, vp);\n")
-
-class CGSpecializedGetter(CGAbstractExternMethod):
- """
- A class for generating the code for a specialized attribute getter
- that the JIT can call with lower overhead.
- """
- def __init__(self, descriptor, attr):
- self.attr = attr
- name = 'get_' + attr.identifier.name
- args = [ Argument('*mut JSContext', 'cx'),
- Argument('JSHandleObject', '_obj'),
- Argument('*const %s' % descriptor.concreteType, 'this'),
- Argument('*mut JSVal', 'vp') ]
- CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
-
- def definition_body(self):
- nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
- self.attr)
-
- return CGWrapper(CGGetterCall([], self.attr.type, nativeName,
- self.descriptor, self.attr),
- pre="let this = JS::from_raw(this);\n"
- "let this = this.root();\n")
-
- @staticmethod
- def makeNativeName(descriptor, attr):
- nativeName = MakeNativeName(attr.identifier.name)
- infallible = ('infallible' in
- descriptor.getExtendedAttributes(attr, getter=True))
- if attr.type.nullable() or not infallible:
- return "Get" + nativeName
-
- return nativeName
-
-
-class CGStaticGetter(CGAbstractStaticBindingMethod):
- """
- A class for generating the C++ code for an IDL static attribute getter.
- """
- def __init__(self, descriptor, attr):
- self.attr = attr
- name = 'get_' + attr.identifier.name
- CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
-
- def generate_code(self):
- nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
- self.attr)
- return CGGetterCall([], self.attr.type, nativeName, self.descriptor,
- self.attr)
-
-
-class CGGenericSetter(CGAbstractBindingMethod):
- """
- A class for generating the Rust code for an IDL attribute setter.
- """
- def __init__(self, descriptor, lenientThis=False):
- args = [Argument('*mut JSContext', 'cx'), Argument('libc::c_uint', 'argc'),
- Argument('*mut JSVal', 'vp')]
- if lenientThis:
- name = "genericLenientSetter"
- unwrapFailureCode = (
- "MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
- "return true;")
- else:
- name = "genericSetter"
- unwrapFailureCode = None
- CGAbstractBindingMethod.__init__(self, descriptor, name, args,
- unwrapFailureCode)
-
- def generate_code(self):
- return CGGeneric(
- "let mut undef = UndefinedValue();\n"
- "let argv: *mut JSVal = if argc != 0 { JS_ARGV(cx, vp) } else { &mut undef as *mut JSVal };\n"
- "let info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "if CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *mut libc::c_void, argv) == 0 {\n"
- " return 0;\n"
- "}\n"
- "*vp = UndefinedValue();\n"
- "return 1;")
-
-class CGSpecializedSetter(CGAbstractExternMethod):
- """
- A class for generating the code for a specialized attribute setter
- that the JIT can call with lower overhead.
- """
- def __init__(self, descriptor, attr):
- self.attr = attr
- name = 'set_' + attr.identifier.name
- args = [ Argument('*mut JSContext', 'cx'),
- Argument('JSHandleObject', '_obj'),
- Argument('*const %s' % descriptor.concreteType, 'this'),
- Argument('*mut JSVal', 'argv')]
- CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
-
- def definition_body(self):
- nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
- self.attr)
- return CGWrapper(CGSetterCall([], self.attr.type, nativeName,
- self.descriptor, self.attr),
- pre="let this = JS::from_raw(this);\n"
- "let this = this.root();\n")
-
- @staticmethod
- def makeNativeName(descriptor, attr):
- return "Set" + MakeNativeName(attr.identifier.name)
-
-
-class CGStaticSetter(CGAbstractStaticBindingMethod):
- """
- A class for generating the C++ code for an IDL static attribute setter.
- """
- def __init__(self, descriptor, attr):
- self.attr = attr
- name = 'set_' + attr.identifier.name
- CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
-
- def generate_code(self):
- nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
- self.attr)
- checkForArg = CGGeneric(
- "let argv = JS_ARGV(cx, vp);\n"
- "if (argc == 0) {\n"
- " throw_type_error(cx, \"Not enough arguments to %s setter.\");\n"
- " return 0;\n"
- "}\n" % self.attr.identifier.name)
- call = CGSetterCall([], self.attr.type, nativeName, self.descriptor,
- self.attr)
- return CGList([checkForArg, call])
-
-
-class CGMemberJITInfo(CGThing):
- """
- A class for generating the JITInfo for a property that points to
- our specialized getter and setter.
- """
- def __init__(self, descriptor, member):
- self.member = member
- self.descriptor = descriptor
-
- def defineJitInfo(self, infoName, opName, infallible):
- protoID = "PrototypeList::id::%s as u32" % self.descriptor.name
- depth = self.descriptor.interface.inheritanceDepth()
- failstr = "true" if infallible else "false"
- return ("\n"
- "static %s: JSJitInfo = JSJitInfo {\n"
- " op: %s as *const u8,\n"
- " protoID: %s,\n"
- " depth: %s,\n"
- " isInfallible: %s, /* False in setters. */\n"
- " isConstant: false /* Only relevant for getters. */\n"
- "};\n" % (infoName, opName, protoID, depth, failstr))
-
- def define(self):
- if self.member.isAttr():
- getterinfo = ("%s_getterinfo" % self.member.identifier.name)
- getter = ("get_%s" % self.member.identifier.name)
- getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
- result = self.defineJitInfo(getterinfo, getter, getterinfal)
- if not self.member.readonly:
- setterinfo = ("%s_setterinfo" % self.member.identifier.name)
- setter = ("set_%s" % self.member.identifier.name)
- # Setters are always fallible, since they have to do a typed unwrap.
- result += self.defineJitInfo(setterinfo, setter, False)
- return result
- if self.member.isMethod():
- methodinfo = ("%s_methodinfo" % self.member.identifier.name)
- # Actually a JSJitMethodOp, but JSJitPropertyOp by struct definition.
- method = ("%s" % self.member.identifier.name)
-
- # Methods are infallible if they are infallible, have no arguments
- # to unwrap, and have a return type that's infallible to wrap up for
- # return.
- methodInfal = False
- sigs = self.member.signatures()
- if len(sigs) == 1:
- # Don't handle overloading. If there's more than one signature,
- # one of them must take arguments.
- sig = sigs[0]
- if len(sig[1]) == 0:
- # No arguments and infallible return boxing
- methodInfal = True
-
- result = self.defineJitInfo(methodinfo, method, methodInfal)
- return result
- raise TypeError("Illegal member type to CGPropertyJITInfo")
-
-def getEnumValueName(value):
- # Some enum values can be empty strings. Others might have weird
- # characters in them. Deal with the former by returning "_empty",
- # deal with possible name collisions from that by throwing if the
- # enum value is actually "_empty", and throw on any value
- # containing non-ASCII chars for now. Replace all chars other than
- # [0-9A-Za-z_] with '_'.
- if re.match("[^\x20-\x7E]", value):
- raise SyntaxError('Enum value "' + value + '" contains non-ASCII characters')
- if re.match("^[0-9]", value):
- raise SyntaxError('Enum value "' + value + '" starts with a digit')
- value = re.sub(r'[^0-9A-Za-z_]', '_', value)
- if re.match("^_[A-Z]|__", value):
- raise SyntaxError('Enum value "' + value + '" is reserved by the C++ spec')
- if value == "_empty":
- raise SyntaxError('"_empty" is not an IDL enum value we support yet')
- if value == "":
- return "_empty"
- return MakeNativeName(value)
-
-class CGEnum(CGThing):
- def __init__(self, enum):
- CGThing.__init__(self)
- inner = """
-use dom::bindings::conversions::ToJSValConvertible;
-use js::jsapi::JSContext;
-use js::jsval::JSVal;
-
-#[repr(uint)]
-#[deriving(Encodable, PartialEq)]
-pub enum valuelist {
- %s
-}
-
-pub static strings: &'static [&'static str] = &[
- %s,
-];
-
-impl ToJSValConvertible for valuelist {
- fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
- strings[*self as uint].to_string().to_jsval(cx)
- }
-}
-""" % (",\n ".join(map(getEnumValueName, enum.values())),
- ",\n ".join(['"%s"' % val for val in enum.values()]))
-
- self.cgRoot = CGList([
- CGNamespace.build([enum.identifier.name + "Values"],
- CGIndenter(CGGeneric(inner)), public=True),
- CGGeneric("pub type %s = self::%sValues::valuelist;\n" %
- (enum.identifier.name, enum.identifier.name)),
- ])
-
- def define(self):
- return self.cgRoot.define()
-
-
-def convertConstIDLValueToRust(value):
- tag = value.type.tag()
- if tag in [IDLType.Tags.int8, IDLType.Tags.uint8,
- IDLType.Tags.int16, IDLType.Tags.uint16,
- IDLType.Tags.int32, IDLType.Tags.uint32,
- IDLType.Tags.int64, IDLType.Tags.uint64,
- IDLType.Tags.float, IDLType.Tags.double]:
- return str(value.value)
-
- if tag == IDLType.Tags.bool:
- return toStringBool(value.value)
-
- raise TypeError("Const value of unhandled type: " + value.type)
-
-class CGConstant(CGThing):
- def __init__(self, constants):
- CGThing.__init__(self)
- self.constants = constants
-
- def define(self):
- def stringDecl(const):
- name = const.identifier.name
- value = convertConstIDLValueToRust(const.value)
- return CGGeneric("pub static %s: %s = %s;\n" % (name, builtinNames[const.value.type.tag()], value))
-
- return CGIndenter(CGList(stringDecl(m) for m in self.constants)).define()
-
-def getUnionTypeTemplateVars(type, descriptorProvider):
- # For dictionaries and sequences we need to pass None as the failureCode
- # for getJSToNativeConversionTemplate.
- # Also, for dictionaries we would need to handle conversion of
- # null/undefined to the dictionary correctly.
- if type.isDictionary() or type.isSequence():
- raise TypeError("Can't handle dictionaries or sequences in unions")
-
- if type.isGeckoInterface():
- name = type.inner.identifier.name
- typeName = descriptorProvider.getDescriptor(name).nativeType
- elif type.isEnum():
- name = type.inner.identifier.name
- typeName = name
- elif type.isArray() or type.isSequence():
- name = str(type)
- #XXXjdm dunno about typeName here
- typeName = "/*" + type.name + "*/"
- elif type.isDOMString():
- name = type.name
- typeName = "DOMString"
- elif type.isPrimitive():
- name = type.name
- typeName = builtinNames[type.tag()]
- else:
- name = type.name
- typeName = "/*" + type.name + "*/"
-
- template, _, _, _ = getJSToNativeConversionTemplate(
- type, descriptorProvider, failureCode="return Ok(None);",
- exceptionCode='return Err(());',
- isDefinitelyObject=True)
-
- assert not type.isObject()
- jsConversion = string.Template(template).substitute({
- "val": "value",
- })
- jsConversion = CGWrapper(CGGeneric(jsConversion), pre="Ok(Some(", post="))")
-
- return {
- "name": name,
- "typeName": typeName,
- "jsConversion": jsConversion,
- }
-
-class CGUnionStruct(CGThing):
- def __init__(self, type, descriptorProvider):
- assert not type.nullable()
- assert not type.hasNullableType
-
- CGThing.__init__(self)
- self.type = type
- self.descriptorProvider = descriptorProvider
-
- def define(self):
- templateVars = map(lambda t: getUnionTypeTemplateVars(t, self.descriptorProvider),
- self.type.flatMemberTypes)
- enumValues = [
- " e%s(%s)," % (v["name"], v["typeName"]) for v in templateVars
- ]
- enumConversions = [
- " e%s(ref inner) => inner.to_jsval(cx)," % v["name"] for v in templateVars
- ]
- return ("""pub enum %s {
-%s
-}
-
-impl ToJSValConvertible for %s {
- fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
- match *self {
-%s
- }
- }
-}
-""") % (self.type, "\n".join(enumValues),
- self.type, "\n".join(enumConversions))
-
-
-class CGUnionConversionStruct(CGThing):
- def __init__(self, type, descriptorProvider):
- assert not type.nullable()
- assert not type.hasNullableType
-
- CGThing.__init__(self)
- self.type = type
- self.descriptorProvider = descriptorProvider
-
- def from_jsval(self):
- memberTypes = self.type.flatMemberTypes
- names = []
- conversions = []
-
- interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
- if len(interfaceMemberTypes) > 0:
- def get_name(memberType):
- if self.type.isGeckoInterface():
- return memberType.inner.identifier.name
-
- return memberType.name
-
- def get_match(name):
- return (
- "match %s::TryConvertTo%s(cx, value) {\n"
- " Err(_) => return Err(()),\n"
- " Ok(Some(value)) => return Ok(e%s(value)),\n"
- " Ok(None) => (),\n"
- "}\n") % (self.type, name, name)
-
- typeNames = [get_name(memberType) for memberType in interfaceMemberTypes]
- interfaceObject = CGList(CGGeneric(get_match(typeName)) for typeName in typeNames)
- names.extend(typeNames)
- else:
- interfaceObject = None
-
- arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
- if len(arrayObjectMemberTypes) > 0:
- assert len(arrayObjectMemberTypes) == 1
- raise TypeError("Can't handle arrays or sequences in unions.")
- else:
- arrayObject = None
-
- dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
- if len(dateObjectMemberTypes) > 0:
- assert len(dateObjectMemberTypes) == 1
- raise TypeError("Can't handle dates in unions.")
- else:
- dateObject = None
-
- callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
- if len(callbackMemberTypes) > 0:
- assert len(callbackMemberTypes) == 1
- raise TypeError("Can't handle callbacks in unions.")
- else:
- callbackObject = None
-
- dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes)
- if len(dictionaryMemberTypes) > 0:
- raise TypeError("No support for unwrapping dictionaries as member "
- "of a union")
- else:
- dictionaryObject = None
-
- if callbackObject or dictionaryObject:
- assert False, "Not currently supported"
- else:
- nonPlatformObject = None
-
- objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
- if len(objectMemberTypes) > 0:
- raise TypeError("Can't handle objects in unions.")
- else:
- object = None
-
- hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object
- if hasObjectTypes:
- assert interfaceObject
- templateBody = CGList([interfaceObject], "\n")
- conversions.append(CGIfWrapper(templateBody, "value.is_object()"))
-
- otherMemberTypes = [
- t for t in memberTypes if t.isPrimitive() or t.isString() or t.isEnum()
- ]
- if len(otherMemberTypes) > 0:
- assert len(otherMemberTypes) == 1
- memberType = otherMemberTypes[0]
- if memberType.isEnum():
- name = memberType.inner.identifier.name
- else:
- name = memberType.name
- match = (
- "match %s::TryConvertTo%s(cx, value) {\n"
- " Err(_) => return Err(()),\n"
- " Ok(Some(value)) => return Ok(e%s(value)),\n"
- " Ok(None) => (),\n"
- "}\n") % (self.type, name, name)
- conversions.append(CGGeneric(match))
- names.append(name)
-
- conversions.append(CGGeneric(
- "throw_not_in_union(cx, \"%s\");\n"
- "Err(())" % ", ".join(names)))
- method = CGWrapper(
- CGIndenter(CGList(conversions, "\n\n")),
- pre="fn from_jsval(cx: *mut JSContext, value: JSVal, _option: ()) -> Result<%s, ()> {\n" % self.type,
- post="\n}")
- return CGWrapper(
- CGIndenter(method),
- pre="impl FromJSValConvertible<()> for %s {\n" % self.type,
- post="\n}")
-
- def try_method(self, t):
- templateVars = getUnionTypeTemplateVars(t, self.descriptorProvider)
- returnType = "Result<Option<%s>, ()>" % templateVars["typeName"]
- jsConversion = templateVars["jsConversion"]
-
- return CGWrapper(
- CGIndenter(jsConversion, 4),
- pre="fn TryConvertTo%s(cx: *mut JSContext, value: JSVal) -> %s {\n" % (t.name, returnType),
- post="\n}")
-
- def define(self):
- from_jsval = self.from_jsval()
- methods = CGIndenter(CGList([
- self.try_method(t) for t in self.type.flatMemberTypes
- ], "\n\n"))
- return """
-%s
-
-impl %s {
-%s
-}
-""" % (from_jsval.define(), self.type, methods.define())
-
-
-class ClassItem:
- """ Use with CGClass """
- def __init__(self, name, visibility):
- self.name = name
- self.visibility = visibility
- def declare(self, cgClass):
- assert False
- def define(self, cgClass):
- assert False
-
-class ClassBase(ClassItem):
- def __init__(self, name, visibility='pub'):
- ClassItem.__init__(self, name, visibility)
- def declare(self, cgClass):
- return '%s %s' % (self.visibility, self.name)
- def define(self, cgClass):
- # Only in the header
- return ''
-
-class ClassMethod(ClassItem):
- def __init__(self, name, returnType, args, inline=False, static=False,
- virtual=False, const=False, bodyInHeader=False,
- templateArgs=None, visibility='public', body=None,
- breakAfterReturnDecl="\n",
- breakAfterSelf="\n", override=False):
- """
- override indicates whether to flag the method as MOZ_OVERRIDE
- """
- assert not override or virtual
- self.returnType = returnType
- self.args = args
- self.inline = False
- self.static = static
- self.virtual = virtual
- self.const = const
- self.bodyInHeader = True
- self.templateArgs = templateArgs
- self.body = body
- self.breakAfterReturnDecl = breakAfterReturnDecl
- self.breakAfterSelf = breakAfterSelf
- self.override = override
- ClassItem.__init__(self, name, visibility)
-
- def getDecorators(self, declaring):
- decorators = []
- if self.inline:
- decorators.append('inline')
- if declaring:
- if self.static:
- decorators.append('static')
- if self.virtual:
- decorators.append('virtual')
- if decorators:
- return ' '.join(decorators) + ' '
- return ''
-
- def getBody(self):
- # Override me or pass a string to constructor
- assert self.body is not None
- return self.body
-
- def declare(self, cgClass):
- templateClause = '<%s>' % ', '.join(self.templateArgs) \
- if self.bodyInHeader and self.templateArgs else ''
- args = ', '.join([a.declare() for a in self.args])
- if self.bodyInHeader:
- body = CGIndenter(CGGeneric(self.getBody())).define()
- body = ' {\n' + body + '\n}'
- else:
- body = ';'
-
- return string.Template("${decorators}%s"
- "${visibility}fn ${name}${templateClause}(${args})${returnType}${const}${override}${body}%s" %
- (self.breakAfterReturnDecl, self.breakAfterSelf)
- ).substitute({
- 'templateClause': templateClause,
- 'decorators': self.getDecorators(True),
- 'returnType': (" -> %s" % self.returnType) if self.returnType else "",
- 'name': self.name,
- 'const': ' const' if self.const else '',
- 'override': ' MOZ_OVERRIDE' if self.override else '',
- 'args': args,
- 'body': body,
- 'visibility': self.visibility + ' ' if self.visibility is not 'priv' else ''
- })
-
- def define(self, cgClass):
- pass
-
-class ClassUsingDeclaration(ClassItem):
- """"
- Used for importing a name from a base class into a CGClass
-
- baseClass is the name of the base class to import the name from
-
- name is the name to import
-
- visibility determines the visibility of the name (public,
- protected, private), defaults to public.
- """
- def __init__(self, baseClass, name, visibility='public'):
- self.baseClass = baseClass
- ClassItem.__init__(self, name, visibility)
-
- def declare(self, cgClass):
- return string.Template("""using ${baseClass}::${name};
-""").substitute({ 'baseClass': self.baseClass,
- 'name': self.name })
-
- def define(self, cgClass):
- return ''
-
-class ClassConstructor(ClassItem):
- """
- Used for adding a constructor to a CGClass.
-
- args is a list of Argument objects that are the arguments taken by the
- constructor.
-
- inline should be True if the constructor should be marked inline.
-
- bodyInHeader should be True if the body should be placed in the class
- declaration in the header.
-
- visibility determines the visibility of the constructor (public,
- protected, private), defaults to private.
-
- explicit should be True if the constructor should be marked explicit.
-
- baseConstructors is a list of strings containing calls to base constructors,
- defaults to None.
-
- body contains a string with the code for the constructor, defaults to empty.
- """
- def __init__(self, args, inline=False, bodyInHeader=False,
- visibility="priv", explicit=False, baseConstructors=None,
- body=""):
- self.args = args
- self.inline = False
- self.bodyInHeader = bodyInHeader
- self.explicit = explicit
- self.baseConstructors = baseConstructors or []
- self.body = body
- ClassItem.__init__(self, None, visibility)
-
- def getDecorators(self, declaring):
- decorators = []
- if self.explicit:
- decorators.append('explicit')
- if self.inline and declaring:
- decorators.append('inline')
- if decorators:
- return ' '.join(decorators) + ' '
- return ''
-
- def getInitializationList(self, cgClass):
- items = [str(c) for c in self.baseConstructors]
- for m in cgClass.members:
- if not m.static:
- initialize = m.body
- if initialize:
- items.append(m.name + "(" + initialize + ")")
-
- if len(items) > 0:
- return '\n : ' + ',\n '.join(items)
- return ''
-
- def getBody(self, cgClass):
- initializers = [" parent: %s" % str(self.baseConstructors[0])]
- return (self.body + (
- "%s {\n"
- "%s\n"
- "}") % (cgClass.name, '\n'.join(initializers)))
-
- def declare(self, cgClass):
- args = ', '.join([a.declare() for a in self.args])
- body = ' ' + self.getBody(cgClass);
- body = stripTrailingWhitespace(body.replace('\n', '\n '))
- if len(body) > 0:
- body += '\n'
- body = ' {\n' + body + '}'
-
- return string.Template("""pub fn ${decorators}new(${args}) -> ${className}${body}
-""").substitute({ 'decorators': self.getDecorators(True),
- 'className': cgClass.getNameString(),
- 'args': args,
- 'body': body })
-
- def define(self, cgClass):
- if self.bodyInHeader:
- return ''
-
- args = ', '.join([a.define() for a in self.args])
-
- body = ' ' + self.getBody()
- body = '\n' + stripTrailingWhitespace(body.replace('\n', '\n '))
- if len(body) > 0:
- body += '\n'
-
- return string.Template("""${decorators}
-${className}::${className}(${args})${initializationList}
-{${body}}
-""").substitute({ 'decorators': self.getDecorators(False),
- 'className': cgClass.getNameString(),
- 'args': args,
- 'initializationList': self.getInitializationList(cgClass),
- 'body': body })
-
-class ClassDestructor(ClassItem):
- """
- Used for adding a destructor to a CGClass.
-
- inline should be True if the destructor should be marked inline.
-
- bodyInHeader should be True if the body should be placed in the class
- declaration in the header.
-
- visibility determines the visibility of the destructor (public,
- protected, private), defaults to private.
-
- body contains a string with the code for the destructor, defaults to empty.
-
- virtual determines whether the destructor is virtual, defaults to False.
- """
- def __init__(self, inline=False, bodyInHeader=False,
- visibility="private", body='', virtual=False):
- self.inline = inline or bodyInHeader
- self.bodyInHeader = bodyInHeader
- self.body = body
- self.virtual = virtual
- ClassItem.__init__(self, None, visibility)
-
- def getDecorators(self, declaring):
- decorators = []
- if self.virtual and declaring:
- decorators.append('virtual')
- if self.inline and declaring:
- decorators.append('inline')
- if decorators:
- return ' '.join(decorators) + ' '
- return ''
-
- def getBody(self):
- return self.body
-
- def declare(self, cgClass):
- if self.bodyInHeader:
- body = ' ' + self.getBody();
- body = stripTrailingWhitespace(body.replace('\n', '\n '))
- if len(body) > 0:
- body += '\n'
- body = '\n{\n' + body + '}'
- else:
- body = ';'
-
- return string.Template("""${decorators}~${className}()${body}
-""").substitute({ 'decorators': self.getDecorators(True),
- 'className': cgClass.getNameString(),
- 'body': body })
-
- def define(self, cgClass):
- if self.bodyInHeader:
- return ''
-
- body = ' ' + self.getBody()
- body = '\n' + stripTrailingWhitespace(body.replace('\n', '\n '))
- if len(body) > 0:
- body += '\n'
-
- return string.Template("""${decorators}
-${className}::~${className}()
-{${body}}
-""").substitute({ 'decorators': self.getDecorators(False),
- 'className': cgClass.getNameString(),
- 'body': body })
-
-class ClassMember(ClassItem):
- def __init__(self, name, type, visibility="priv", static=False,
- body=None):
- self.type = type;
- self.static = static
- self.body = body
- ClassItem.__init__(self, name, visibility)
-
- def declare(self, cgClass):
- return '%s %s: %s,\n' % (self.visibility, self.name, self.type)
-
- def define(self, cgClass):
- if not self.static:
- return ''
- if self.body:
- body = " = " + self.body
- else:
- body = ""
- return '%s %s::%s%s;\n' % (self.type, cgClass.getNameString(),
- self.name, body)
-
-class ClassTypedef(ClassItem):
- def __init__(self, name, type, visibility="public"):
- self.type = type
- ClassItem.__init__(self, name, visibility)
-
- def declare(self, cgClass):
- return 'typedef %s %s;\n' % (self.type, self.name)
-
- def define(self, cgClass):
- # Only goes in the header
- return ''
-
-class ClassEnum(ClassItem):
- def __init__(self, name, entries, values=None, visibility="public"):
- self.entries = entries
- self.values = values
- ClassItem.__init__(self, name, visibility)
-
- def declare(self, cgClass):
- entries = []
- for i in range(0, len(self.entries)):
- if not self.values or i >= len(self.values):
- entry = '%s' % self.entries[i]
- else:
- entry = '%s = %s' % (self.entries[i], self.values[i])
- entries.append(entry)
- name = '' if not self.name else ' ' + self.name
- return 'enum%s\n{\n %s\n};\n' % (name, ',\n '.join(entries))
-
- def define(self, cgClass):
- # Only goes in the header
- return ''
-
-class ClassUnion(ClassItem):
- def __init__(self, name, entries, visibility="public"):
- self.entries = [entry + ";" for entry in entries]
- ClassItem.__init__(self, name, visibility)
-
- def declare(self, cgClass):
- return 'union %s\n{\n %s\n};\n' % (self.name, '\n '.join(self.entries))
-
- def define(self, cgClass):
- # Only goes in the header
- return ''
-
-class CGClass(CGThing):
- def __init__(self, name, bases=[], members=[], constructors=[],
- destructor=None, methods=[],
- typedefs = [], enums=[], unions=[], templateArgs=[],
- templateSpecialization=[], isStruct=False,
- disallowCopyConstruction=False, indent='',
- decorators='',
- extradeclarations='',
- extradefinitions=''):
- CGThing.__init__(self)
- self.name = name
- self.bases = bases
- self.members = members
- self.constructors = constructors
- # We store our single destructor in a list, since all of our
- # code wants lists of members.
- self.destructors = [destructor] if destructor else []
- self.methods = methods
- self.typedefs = typedefs
- self.enums = enums
- self.unions = unions
- self.templateArgs = templateArgs
- self.templateSpecialization = templateSpecialization
- self.isStruct = isStruct
- self.disallowCopyConstruction = disallowCopyConstruction
- self.indent = indent
- self.decorators = decorators
- self.extradeclarations = extradeclarations
- self.extradefinitions = extradefinitions
-
- def getNameString(self):
- className = self.name
- if self.templateSpecialization:
- className = className + \
- '<%s>' % ', '.join([str(a) for a
- in self.templateSpecialization])
- return className
-
- def define(self):
- result = ''
- if self.templateArgs:
- templateArgs = [a.declare() for a in self.templateArgs]
- templateArgs = templateArgs[len(self.templateSpecialization):]
- result = result + self.indent + 'template <%s>\n' \
- % ','.join([str(a) for a in templateArgs])
-
- if self.templateSpecialization:
- specialization = \
- '<%s>' % ', '.join([str(a) for a in self.templateSpecialization])
- else:
- specialization = ''
-
- myself = ''
- if self.decorators != '':
- myself += self.decorators + '\n'
- myself += '%spub struct %s%s' % (self.indent, self.name, specialization)
- result += myself
-
- assert len(self.bases) == 1 #XXjdm Can we support multiple inheritance?
-
- result += '{\n%s\n' % self.indent
-
- if self.bases:
- self.members = [ClassMember("parent", self.bases[0].name, "pub")] + self.members
-
- result += CGIndenter(CGGeneric(self.extradeclarations),
- len(self.indent)).define()
-
- def declareMembers(cgClass, memberList):
- result = ''
-
- for member in memberList:
- declaration = member.declare(cgClass)
- declaration = CGIndenter(CGGeneric(declaration)).define()
- result = result + declaration
- return result
-
- if self.disallowCopyConstruction:
- class DisallowedCopyConstructor(object):
- def __init__(self):
- self.visibility = "private"
- def declare(self, cgClass):
- name = cgClass.getNameString()
- return ("%s(const %s&) MOZ_DELETE;\n"
- "void operator=(const %s) MOZ_DELETE;\n" % (name, name, name))
- disallowedCopyConstructors = [DisallowedCopyConstructor()]
- else:
- disallowedCopyConstructors = []
-
- order = [(self.enums, ''), (self.unions, ''),
- (self.typedefs, ''), (self.members, '')]
-
- for (memberList, separator) in order:
- memberString = declareMembers(self, memberList)
- if self.indent:
- memberString = CGIndenter(CGGeneric(memberString),
- len(self.indent)).define()
- result = result + memberString
-
- result += self.indent + '}\n\n'
- result += 'impl %s {\n' % self.name
-
- order = [(self.constructors + disallowedCopyConstructors, '\n'),
- (self.destructors, '\n'), (self.methods, '\n)')]
- for (memberList, separator) in order:
- memberString = declareMembers(self, memberList)
- if self.indent:
- memberString = CGIndenter(CGGeneric(memberString),
- len(self.indent)).define()
- result = result + memberString
-
- result += "}"
- return result
-
-class CGProxySpecialOperation(CGPerSignatureCall):
- """
- Base class for classes for calling an indexed or named special operation
- (don't use this directly, use the derived classes below).
- """
- def __init__(self, descriptor, operation):
- nativeName = MakeNativeName(operation)
- operation = descriptor.operations[operation]
- assert len(operation.signatures()) == 1
- signature = operation.signatures()[0]
-
- (returnType, arguments) = signature
-
- # We pass len(arguments) as the final argument so that the
- # CGPerSignatureCall won't do any argument conversion of its own.
- CGPerSignatureCall.__init__(self, returnType, "", arguments, nativeName,
- False, descriptor, operation,
- len(arguments))
-
- if operation.isSetter() or operation.isCreator():
- # arguments[0] is the index or name of the item that we're setting.
- argument = arguments[1]
- template, _, declType, needsRooting = getJSToNativeConversionTemplate(
- argument.type, descriptor, treatNullAs=argument.treatNullAs)
- templateValues = {
- "val": "(*desc).value",
- }
- self.cgRoot.prepend(instantiateJSToNativeConversionTemplate(
- template, templateValues, declType, argument.identifier.name,
- needsRooting))
- elif operation.isGetter():
- self.cgRoot.prepend(CGGeneric("let mut found = false;"))
-
- def getArguments(self):
- def process(arg):
- argVal = arg.identifier.name
- if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback():
- argVal += ".root_ref()"
- return argVal
- args = [(a, process(a)) for a in self.arguments]
- if self.idlNode.isGetter():
- args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean],
- self.idlNode),
- "&mut found"))
- return args
-
- def wrap_return_value(self):
- if not self.idlNode.isGetter() or self.templateValues is None:
- return ""
-
- wrap = CGGeneric(wrapForType(**self.templateValues))
- wrap = CGIfWrapper(wrap, "found")
- return "\n" + wrap.define()
-
-class CGProxyIndexedGetter(CGProxySpecialOperation):
- """
- Class to generate a call to an indexed getter. If templateValues is not None
- the returned value will be wrapped with wrapForType using templateValues.
- """
- def __init__(self, descriptor, templateValues=None):
- self.templateValues = templateValues
- CGProxySpecialOperation.__init__(self, descriptor, 'IndexedGetter')
-
-class CGProxyIndexedSetter(CGProxySpecialOperation):
- """
- Class to generate a call to an indexed setter.
- """
- def __init__(self, descriptor):
- CGProxySpecialOperation.__init__(self, descriptor, 'IndexedSetter')
-
-class CGProxyNamedGetter(CGProxySpecialOperation):
- """
- Class to generate a call to an named getter. If templateValues is not None
- the returned value will be wrapped with wrapForType using templateValues.
- """
- def __init__(self, descriptor, templateValues=None):
- self.templateValues = templateValues
- CGProxySpecialOperation.__init__(self, descriptor, 'NamedGetter')
-
-class CGProxyNamedSetter(CGProxySpecialOperation):
- """
- Class to generate a call to a named setter.
- """
- def __init__(self, descriptor):
- CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter')
-
-class CGProxyUnwrap(CGAbstractMethod):
- def __init__(self, descriptor):
- args = [Argument('*mut JSObject', 'obj')]
- CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*const ' + descriptor.concreteType, args, alwaysInline=True)
-
- def definition_body(self):
- return CGGeneric("""/*if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
- obj = js::UnwrapObject(obj);
-}*/
-//MOZ_ASSERT(IsProxy(obj));
-let box_ = GetProxyPrivate(obj).to_private() as *const %s;
-return box_;""" % self.descriptor.concreteType)
-
-class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
- def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('jsid', 'id'), Argument('bool', 'set'),
- Argument('*mut JSPropertyDescriptor', 'desc')]
- CGAbstractExternMethod.__init__(self, descriptor, "getOwnPropertyDescriptor",
- "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- indexedGetter = self.descriptor.operations['IndexedGetter']
- indexedSetter = self.descriptor.operations['IndexedSetter']
-
- setOrIndexedGet = ""
- if indexedGetter or indexedSetter:
- setOrIndexedGet += "let index = GetArrayIndexFromId(cx, id);\n"
-
- if indexedGetter:
- readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
- fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn true;" % readonly
- templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor}
- get = ("if index.is_some() {\n" +
- " let index = index.unwrap();\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" +
- "}\n")
-
- if indexedSetter or self.descriptor.operations['NamedSetter']:
- setOrIndexedGet += "if set != 0 {\n"
- if indexedSetter:
- setOrIndexedGet += (" if index.is_some() {\n" +
- " let index = index.unwrap();\n")
- if not 'IndexedCreator' in self.descriptor.operations:
- # FIXME need to check that this is a 'supported property index'
- assert False
- setOrIndexedGet += (" FillPropertyDescriptor(&mut *desc, proxy, false);\n" +
- " return true;\n" +
- " }\n")
- if self.descriptor.operations['NamedSetter']:
- setOrIndexedGet += " if RUST_JSID_IS_STRING(id) {\n"
- if not 'NamedCreator' in self.descriptor.operations:
- # FIXME need to check that this is a 'supported property name'
- assert False
- setOrIndexedGet += (" FillPropertyDescriptor(&mut *desc, proxy, false);\n" +
- " return true;\n" +
- " }\n")
- setOrIndexedGet += "}"
- if indexedGetter:
- setOrIndexedGet += (" else {\n" +
- CGIndenter(CGGeneric(get)).define() +
- "}")
- setOrIndexedGet += "\n\n"
- elif indexedGetter:
- setOrIndexedGet += ("if !set {\n" +
- CGIndenter(CGGeneric(get)).define() +
- "}\n\n")
-
- namedGetter = self.descriptor.operations['NamedGetter']
- if namedGetter:
- readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
- fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn true;" % readonly
- templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor}
- # Once we start supporting OverrideBuiltins we need to make
- # ResolveOwnProperty or EnumerateOwnProperties filter out named
- # properties that shadow prototype properties.
- namedGet = ("\n" +
- "if !set && RUST_JSID_IS_STRING(id) != 0 && !HasPropertyOnPrototype(cx, proxy, id) {\n" +
- " let name = jsid_to_str(cx, id);\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" +
- "}\n")
- else:
- namedGet = ""
-
- return setOrIndexedGet + """let expando: *mut JSObject = GetExpandoObject(proxy);
-//if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
-if expando.is_not_null() {
- let flags = if set { JSRESOLVE_ASSIGNING } else { 0 } | JSRESOLVE_QUALIFIED;
- if JS_GetPropertyDescriptorById(cx, expando, id, flags, desc) == 0 {
- return false;
- }
- if (*desc).obj.is_not_null() {
- // Pretend the property lives on the wrapper.
- (*desc).obj = proxy;
- return true;
- }
-}
-""" + namedGet + """
-(*desc).obj = ptr::mut_null();
-return true;"""
-
- def definition_body(self):
- return CGGeneric(self.getBody())
-
-class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
- def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('jsid', 'id'),
- Argument('*const JSPropertyDescriptor', 'desc')]
- CGAbstractExternMethod.__init__(self, descriptor, "defineProperty", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- set = ""
-
- indexedSetter = self.descriptor.operations['IndexedSetter']
- if indexedSetter:
- if not (self.descriptor.operations['IndexedCreator'] is indexedSetter):
- raise TypeError("Can't handle creator that's different from the setter")
- set += ("let index = GetArrayIndexFromId(cx, id);\n" +
- "if index.is_some() {\n" +
- " let index = index.unwrap();\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyIndexedSetter(self.descriptor)).define() +
- " return true;\n" +
- "}\n")
- elif self.descriptor.operations['IndexedGetter']:
- set += ("if GetArrayIndexFromId(cx, id).is_some() {\n" +
- " return false;\n" +
- " //return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
- "}\n") % self.descriptor.name
-
- namedSetter = self.descriptor.operations['NamedSetter']
- if namedSetter:
- if not self.descriptor.operations['NamedCreator'] is namedSetter:
- raise TypeError("Can't handle creator that's different from the setter")
- set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" +
- " let name = jsid_to_str(cx, id);\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyNamedSetter(self.descriptor)).define() + "\n" +
- "}\n")
- elif self.descriptor.operations['NamedGetter']:
- set += ("if RUST_JSID_IS_STRING(id) {\n" +
- " let name = jsid_to_str(cx, id);\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyNamedGetter(self.descriptor)).define() +
- " if (found) {\n"
- " return false;\n" +
- " //return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
- " }\n" +
- " return true;\n"
- "}\n") % (self.descriptor.name)
- return set + """return proxyhandler::defineProperty_(%s);""" % ", ".join(a.name for a in self.args)
-
- def definition_body(self):
- return CGGeneric(self.getBody())
-
-class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
- def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('jsid', 'id'), Argument('*mut bool', 'bp')]
- CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- indexedGetter = self.descriptor.operations['IndexedGetter']
- if indexedGetter:
- indexed = ("let index = GetArrayIndexFromId(cx, id);\n" +
- "if index.is_some() {\n" +
- " let index = index.unwrap();\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" +
- " *bp = found;\n" +
- " return true;\n" +
- "}\n\n")
- else:
- indexed = ""
-
- namedGetter = self.descriptor.operations['NamedGetter']
- if namedGetter:
- named = ("if RUST_JSID_IS_STRING(id) != 0 && !HasPropertyOnPrototype(cx, proxy, id) {\n" +
- " let name = jsid_to_str(cx, id);\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" +
- " *bp = found;\n"
- " return true;\n"
- "}\n" +
- "\n")
- else:
- named = ""
-
- return indexed + """let expando: *mut JSObject = GetExpandoObject(proxy);
-if expando.is_not_null() {
- let mut b: JSBool = 1;
- let ok = JS_HasPropertyById(cx, expando, id, &mut b) != 0;
- *bp = b != 0;
- if !ok || *bp {
- return ok;
- }
-}
-
-""" + named + """*bp = false;
-return true;"""
-
- def definition_body(self):
- return CGGeneric(self.getBody())
-
-class CGDOMJSProxyHandler_get(CGAbstractExternMethod):
- def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('*mut JSObject', 'receiver'), Argument('jsid', 'id'),
- Argument('*mut JSVal', 'vp')]
- CGAbstractExternMethod.__init__(self, descriptor, "get", "bool", args)
- self.descriptor = descriptor
- def getBody(self):
- getFromExpando = """let expando = GetExpandoObject(proxy);
-if expando.is_not_null() {
- let mut hasProp = 0;
- if JS_HasPropertyById(cx, expando, id, &mut hasProp) == 0 {
- return false;
- }
-
- if hasProp != 0 {
- return JS_GetPropertyById(cx, expando, id, vp) != 0;
- }
-}"""
-
- templateValues = {
- 'jsvalRef': '*vp',
- 'successCode': 'return true;',
- }
-
- indexedGetter = self.descriptor.operations['IndexedGetter']
- if indexedGetter:
- getIndexedOrExpando = ("let index = GetArrayIndexFromId(cx, id);\n" +
- "if index.is_some() {\n" +
- " let index = index.unwrap();\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define())
- getIndexedOrExpando += """
- // Even if we don't have this index, we don't forward the
- // get on to our expando object.
-} else {
- %s
-}
-""" % (stripTrailingWhitespace(getFromExpando.replace('\n', '\n ')))
- else:
- getIndexedOrExpando = getFromExpando + "\n"
-
- namedGetter = self.descriptor.operations['NamedGetter']
- if namedGetter and False: #XXXjdm unfinished
- getNamed = ("if (JSID_IS_STRING(id)) {\n" +
- " let name = jsid_to_str(cx, id);\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = JS::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() +
- "}\n") % (self.descriptor.concreteType)
- else:
- getNamed = ""
-
- return """//MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
- //"Should not have a XrayWrapper here");
-
-%s
-let mut found = false;
-if !GetPropertyOnPrototype(cx, proxy, id, &mut found, vp) {
- return false;
-}
-
-if found {
- return true;
-}
-%s
-*vp = UndefinedValue();
-return true;""" % (getIndexedOrExpando, getNamed)
-
- def definition_body(self):
- return CGGeneric(self.getBody())
-
-class CGDOMJSProxyHandler_obj_toString(CGAbstractExternMethod):
- def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy')]
- CGAbstractExternMethod.__init__(self, descriptor, "obj_toString", "*mut JSString", args)
- self.descriptor = descriptor
- def getBody(self):
- stringifier = self.descriptor.operations['Stringifier']
- if stringifier:
- nativeName = MakeNativeName(stringifier.identifier.name)
- signature = stringifier.signatures()[0]
- returnType = signature[0]
- extendedAttributes = self.descriptor.getExtendedAttributes(stringifier)
- infallible = 'infallible' in extendedAttributes
- if not infallible:
- error = CGGeneric(
- ('ThrowMethodFailedWithDetails(cx, rv, "%s", "toString");\n' +
- "return NULL;") % self.descriptor.interface.identifier.name)
- else:
- error = None
- call = CGCallGenerator(error, [], "", returnType, extendedAttributes, self.descriptor, nativeName, False, object="UnwrapProxy(proxy)")
- return call.define() + """
-
-JSString* jsresult;
-return xpc_qsStringToJsstring(cx, result, &jsresult) ? jsresult : NULL;"""
-
- return """let s = "%s".to_c_str();
- _obj_toString(cx, s.as_ptr())""" % self.descriptor.name
-
- def definition_body(self):
- return CGGeneric(self.getBody())
-
-class CGAbstractClassHook(CGAbstractExternMethod):
- """
- Meant for implementing JSClass hooks, like Finalize or Trace. Does very raw
- 'this' unwrapping as it assumes that the unwrapped type is always known.
- """
- def __init__(self, descriptor, name, returnType, args):
- CGAbstractExternMethod.__init__(self, descriptor, name, returnType,
- args)
-
- def definition_body_prologue(self):
- return CGGeneric("""\
-let this: *const %s = unwrap::<%s>(obj);
-""" % (self.descriptor.concreteType, self.descriptor.concreteType))
-
- def definition_body(self):
- return CGList([
- self.definition_body_prologue(),
- self.generate_code(),
- ])
-
- def generate_code(self):
- # Override me
- assert(False)
-
-def finalizeHook(descriptor, hookName, context):
- release = """let val = JS_GetReservedSlot(obj, dom_object_slot(obj));
-let _: Box<%s> = mem::transmute(val.to_private());
-debug!("%s finalize: {:p}", this);
-""" % (descriptor.concreteType, descriptor.concreteType)
- return release
-
-class CGClassTraceHook(CGAbstractClassHook):
- """
- A hook to trace through our native object; used for GC and CC
- """
- def __init__(self, descriptor):
- args = [Argument('*mut JSTracer', 'trc'), Argument('*mut JSObject', 'obj')]
- CGAbstractClassHook.__init__(self, descriptor, TRACE_HOOK_NAME, 'void',
- args)
-
- def generate_code(self):
- return CGGeneric("(*this).trace(%s);" % self.args[0].name)
-
-class CGClassConstructHook(CGAbstractExternMethod):
- """
- JS-visible constructor for our objects
- """
- def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('u32', 'argc'), Argument('*mut JSVal', 'vp')]
- CGAbstractExternMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME,
- 'JSBool', args)
- self._ctor = self.descriptor.interface.ctor()
-
- def define(self):
- if not self._ctor:
- return ""
- return CGAbstractExternMethod.define(self)
-
- def definition_body(self):
- preamble = CGGeneric("""\
-let global = global_object_for_js_object(JS_CALLEE(cx, vp).to_object());
-let global = global.root();
-""")
- nativeName = MakeNativeName(self._ctor.identifier.name)
- callGenerator = CGMethodCall(["&global.root_ref()"], nativeName, True,
- self.descriptor, self._ctor)
- return CGList([preamble, callGenerator])
-
-class CGClassFinalizeHook(CGAbstractClassHook):
- """
- A hook for finalize, used to release our native object.
- """
- def __init__(self, descriptor):
- args = [Argument('*mut JSFreeOp', 'fop'), Argument('*mut JSObject', 'obj')]
- CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME,
- 'void', args)
-
- def generate_code(self):
- return CGGeneric(finalizeHook(self.descriptor, self.name, self.args[0].name))
-
-class CGDOMJSProxyHandlerDOMClass(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
- self.descriptor = descriptor
-
- def define(self):
- return """
-static Class: DOMClass = """ + DOMClass(self.descriptor) + """;
-
-"""
-
-
-class CGInterfaceTrait(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
-
- def argument_type(ty, optional=False, defaultValue=None, variadic=False):
- _, _, declType, _ = getJSToNativeConversionTemplate(
- ty, descriptor, isArgument=True)
-
- if variadic:
- declType = CGWrapper(declType, pre="Vec<", post=">")
- elif optional and not defaultValue:
- declType = CGWrapper(declType, pre="Option<", post=">")
-
- if ty.isGeckoInterface() and not (ty.nullable() or optional):
- declType = CGWrapper(declType, pre="&")
- elif ty.isDictionary():
- declType = CGWrapper(declType, pre="&")
-
- return declType.define()
-
- def attribute_arguments(needCx, argument=None):
- if needCx:
- yield "cx", "*mut JSContext"
-
- if argument:
- yield "value", argument_type(argument)
-
- def method_arguments(returnType, arguments, trailing=None):
- if needCx(returnType, arguments, True):
- yield "cx", "*mut JSContext"
-
- for argument in arguments:
- ty = argument_type(argument.type, argument.optional,
- argument.defaultValue, argument.variadic)
- yield CGDictionary.makeMemberName(argument.identifier.name), ty
-
- if trailing:
- yield trailing
-
- def return_type(rettype, infallible):
- result = getRetvalDeclarationForType(rettype, descriptor)
- if not infallible:
- result = CGWrapper(result, pre="Fallible<", post=">")
- return result.define()
-
- def members():
- for m in descriptor.interface.members:
- if m.isMethod() and not m.isStatic():
- name = CGSpecializedMethod.makeNativeName(descriptor, m)
- infallible = 'infallible' in descriptor.getExtendedAttributes(m)
- for idx, (rettype, arguments) in enumerate(m.signatures()):
- arguments = method_arguments(rettype, arguments)
- rettype = return_type(rettype, infallible)
- yield name + ('_' * idx), arguments, rettype
- elif m.isAttr() and not m.isStatic():
- name = CGSpecializedGetter.makeNativeName(descriptor, m)
- infallible = 'infallible' in descriptor.getExtendedAttributes(m, getter=True)
- needCx = typeNeedsCx(m.type)
- yield name, attribute_arguments(needCx), return_type(m.type, infallible)
-
- if not m.readonly:
- name = CGSpecializedSetter.makeNativeName(descriptor, m)
- infallible = 'infallible' in descriptor.getExtendedAttributes(m, setter=True)
- if infallible:
- rettype = "()"
- else:
- rettype = "ErrorResult"
- yield name, attribute_arguments(needCx, m.type), rettype
-
- if descriptor.proxy:
- for name, operation in descriptor.operations.iteritems():
- if not operation:
- continue
-
- assert len(operation.signatures()) == 1
- rettype, arguments = operation.signatures()[0]
-
- infallible = 'infallible' in descriptor.getExtendedAttributes(operation)
- arguments = method_arguments(rettype, arguments, ("found", "&mut bool"))
- rettype = return_type(rettype, infallible)
- yield name, arguments, rettype
-
- def fmt(arguments):
- return "".join(", %s: %s" % argument for argument in arguments)
-
- methods = CGList([
- CGGeneric("fn %s(&self%s) -> %s;\n" % (name, fmt(arguments), rettype))
- for name, arguments, rettype in members()
- ], "")
- self.cgRoot = CGWrapper(CGIndenter(methods),
- pre="pub trait %sMethods {\n" % descriptor.interface.identifier.name,
- post="}")
-
- def define(self):
- return self.cgRoot.define()
-
-
-class CGDescriptor(CGThing):
- def __init__(self, descriptor):
- CGThing.__init__(self)
-
- assert not descriptor.interface.isCallback()
-
- cgThings = []
- cgThings.append(CGGetProtoObjectMethod(descriptor))
- if descriptor.interface.hasInterfaceObject():
- # https://github.com/mozilla/servo/issues/2665
- # cgThings.append(CGGetConstructorObjectMethod(descriptor))
- pass
-
- (hasMethod, hasGetter, hasLenientGetter,
- hasSetter, hasLenientSetter) = False, False, False, False, False
- for m in descriptor.interface.members:
- if m.isMethod() and not m.isIdentifierLess():
- if m.isStatic():
- assert descriptor.interface.hasInterfaceObject()
- cgThings.append(CGStaticMethod(descriptor, m))
- else:
- cgThings.append(CGSpecializedMethod(descriptor, m))
- cgThings.append(CGMemberJITInfo(descriptor, m))
- hasMethod = True
- elif m.isAttr():
- if m.isStatic():
- assert descriptor.interface.hasInterfaceObject()
- cgThings.append(CGStaticGetter(descriptor, m))
- else:
- cgThings.append(CGSpecializedGetter(descriptor, m))
- if m.hasLenientThis():
- hasLenientGetter = True
- else:
- hasGetter = True
-
- if not m.readonly:
- if m.isStatic():
- assert descriptor.interface.hasInterfaceObject()
- cgThings.append(CGStaticSetter(descriptor, m))
- else:
- cgThings.append(CGSpecializedSetter(descriptor, m))
- if m.hasLenientThis():
- hasLenientSetter = True
- else:
- hasSetter = True
-
- if not m.isStatic():
- cgThings.append(CGMemberJITInfo(descriptor, m))
- if hasMethod:
- cgThings.append(CGGenericMethod(descriptor))
- if hasGetter:
- cgThings.append(CGGenericGetter(descriptor))
- if hasLenientGetter:
- pass
- if hasSetter:
- cgThings.append(CGGenericSetter(descriptor))
- if hasLenientSetter:
- pass
-
- if descriptor.concrete:
- cgThings.append(CGClassFinalizeHook(descriptor))
- cgThings.append(CGClassTraceHook(descriptor))
-
- if descriptor.interface.hasInterfaceObject():
- cgThings.append(CGClassConstructHook(descriptor))
- cgThings.append(CGInterfaceObjectJSClass(descriptor))
-
- cgThings.append(CGPrototypeJSClass(descriptor))
-
- properties = PropertyArrays(descriptor)
- cgThings.append(CGGeneric(str(properties)))
- cgThings.append(CGNativeProperties(descriptor, properties))
- cgThings.append(CGNativePropertyHooks(descriptor, properties))
- cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
-
- cgThings.append(CGNamespace.build([descriptor.name + "Constants"],
- CGConstant(m for m in descriptor.interface.members if m.isConst()),
- public=True))
-
- if descriptor.interface.hasInterfaceObject():
- cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
-
- if descriptor.proxy:
- cgThings.append(CGDefineProxyHandler(descriptor))
-
- if descriptor.concrete:
- if descriptor.proxy:
- #cgThings.append(CGProxyIsProxy(descriptor))
- cgThings.append(CGProxyUnwrap(descriptor))
- cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor))
- cgThings.append(CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor))
- cgThings.append(CGDOMJSProxyHandler_obj_toString(descriptor))
- cgThings.append(CGDOMJSProxyHandler_get(descriptor))
- cgThings.append(CGDOMJSProxyHandler_hasOwn(descriptor))
- if descriptor.operations['IndexedSetter'] or descriptor.operations['NamedSetter']:
- cgThings.append(CGDOMJSProxyHandler_defineProperty(descriptor))
-
- #cgThings.append(CGDOMJSProxyHandler(descriptor))
- #cgThings.append(CGIsMethod(descriptor))
- pass
- else:
- cgThings.append(CGDOMJSClass(descriptor))
- pass
-
- cgThings.append(CGWrapMethod(descriptor))
-
- cgThings.append(CGIDLInterface(descriptor))
- cgThings.append(CGInterfaceTrait(descriptor))
-
- cgThings = CGList(cgThings, "\n")
- cgThings = CGWrapper(cgThings, pre='\n', post='\n')
- #self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
- # cgThings),
- # post='\n')
- self.cgRoot = cgThings
-
- def define(self):
- return self.cgRoot.define()
-
-class CGNamespacedEnum(CGThing):
- def __init__(self, namespace, enumName, names, values, comment="", deriving=""):
-
- if not values:
- values = []
-
- # Account for explicit enum values.
- entries = []
- for i in range(0, len(names)):
- if len(values) > i and values[i] is not None:
- entry = "%s = %s" % (names[i], values[i])
- else:
- entry = names[i]
- entries.append(entry)
-
- # Append a Count.
- entries.append(enumName + 'Count = ' + str(len(entries)))
-
- # Indent.
- entries = [' ' + e for e in entries]
-
- # Build the enum body.
- enumstr = comment + 'pub enum %s {\n%s\n}\n' % (enumName, ',\n'.join(entries))
- if deriving:
- enumstr = ('#[deriving(%s)]\n' % deriving) + enumstr
- curr = CGGeneric(enumstr)
-
- # Add some whitespace padding.
- curr = CGWrapper(curr, pre='\n',post='\n')
-
- # Add the namespace.
- curr = CGNamespace(namespace, curr, public=True)
-
- # Add the typedef
- #typedef = '\ntypedef %s::%s %s;\n\n' % (namespace, enumName, enumName)
- #curr = CGList([curr, CGGeneric(typedef)])
-
- # Save the result.
- self.node = curr
-
- def define(self):
- return self.node.define()
-
-class CGDictionary(CGThing):
- def __init__(self, dictionary, descriptorProvider):
- self.dictionary = dictionary;
- if all(CGDictionary(d, descriptorProvider).generatable for
- d in CGDictionary.getDictionaryDependencies(dictionary)):
- self.generatable = True
- else:
- self.generatable = False
- # Nothing else to do here
- return
- self.memberInfo = [
- (member,
- getJSToNativeConversionTemplate(member.type,
- descriptorProvider,
- isMember="Dictionary",
- defaultValue=member.defaultValue,
- failureCode="return Err(());",
- exceptionCode="return Err(());"))
- for member in dictionary.members ]
-
- def define(self):
- if not self.generatable:
- return ""
- return self.struct() + "\n" + self.impl()
-
- def struct(self):
- d = self.dictionary
- if d.parent:
- inheritance = " pub parent: %s::%s<'a, 'b>,\n" % (self.makeModuleName(d.parent),
- self.makeClassName(d.parent))
- else:
- inheritance = ""
- memberDecls = [" pub %s: %s," %
- (self.makeMemberName(m[0].identifier.name), self.getMemberType(m))
- for m in self.memberInfo]
-
- return (string.Template(
- "pub struct ${selfName}<'a, 'b> {\n" +
- "${inheritance}" +
- "\n".join(memberDecls) + "\n" +
- "}").substitute( { "selfName": self.makeClassName(d),
- "inheritance": inheritance }))
-
- def impl(self):
- d = self.dictionary
- if d.parent:
- initParent = ("parent: match %s::%s::new(cx, val) {\n"
- " Ok(parent) => parent,\n"
- " Err(_) => return Err(()),\n"
- "},\n") % (self.makeModuleName(d.parent),
- self.makeClassName(d.parent))
- else:
- initParent = ""
-
- def memberInit(memberInfo):
- member, _ = memberInfo
- name = self.makeMemberName(member.identifier.name)
- conversion = self.getMemberConversion(memberInfo)
- return CGGeneric("%s: %s,\n" % (name, conversion.define()))
-
- memberInits = CGList([memberInit(m) for m in self.memberInfo])
-
- return string.Template(
- "impl<'a, 'b> ${selfName}<'a, 'b> {\n"
- " pub fn empty() -> ${selfName}<'a, 'b> {\n"
- " ${selfName}::new(ptr::mut_null(), NullValue()).unwrap()\n"
- " }\n"
- " pub fn new(cx: *mut JSContext, val: JSVal) -> Result<${selfName}<'a, 'b>, ()> {\n"
- " let object = if val.is_null_or_undefined() {\n"
- " ptr::mut_null()\n"
- " } else if val.is_object() {\n"
- " val.to_object()\n"
- " } else {\n"
- " throw_type_error(cx, \"Value not an object.\");\n"
- " return Err(());\n"
- " };\n"
- " Ok(${selfName} {\n"
- "${initParent}"
- "${initMembers}"
- " })\n"
- " }\n"
- "}").substitute({
- "selfName": self.makeClassName(d),
- "initParent": CGIndenter(CGGeneric(initParent), indentLevel=6).define(),
- "initMembers": CGIndenter(memberInits, indentLevel=6).define(),
- })
-
- @staticmethod
- def makeDictionaryName(dictionary):
- return dictionary.identifier.name
-
- def makeClassName(self, dictionary):
- return self.makeDictionaryName(dictionary)
-
- @staticmethod
- def makeModuleName(dictionary):
- name = dictionary.identifier.name
- if name.endswith('Init'):
- return toBindingNamespace(name.replace('Init', ''))
- #XXXjdm This breaks on the test webidl files, sigh.
- #raise TypeError("No idea how to find this dictionary's definition: " + name)
- return "/* uh oh */ %s" % name
-
- def getMemberType(self, memberInfo):
- member, (_, _, declType, _) = memberInfo
- if not member.defaultValue:
- declType = CGWrapper(declType, pre="Option<", post=">")
- return declType.define()
-
- def getMemberConversion(self, memberInfo):
- def indent(s):
- return CGIndenter(CGGeneric(s), 8).define()
-
- member, (templateBody, default, declType, _) = memberInfo
- replacements = { "val": "value" }
- conversion = string.Template(templateBody).substitute(replacements)
-
- assert (member.defaultValue is None) == (default is None)
- if not default:
- default = "None"
- conversion = "Some(%s)" % conversion
-
- conversion = (
- "match get_dictionary_property(cx, object, \"%s\") {\n"
- " Err(()) => return Err(()),\n"
- " Ok(Some(value)) => {\n"
- "%s\n"
- " },\n"
- " Ok(None) => {\n"
- "%s\n"
- " },\n"
- "}") % (member.identifier.name, indent(conversion), indent(default))
-
- return CGGeneric(conversion)
-
- @staticmethod
- def makeIdName(name):
- return name + "_id"
-
- @staticmethod
- def makeMemberName(name):
- # Can't use Rust keywords as member names.
- if name == "type":
- return name + "_"
- return name
-
- @staticmethod
- def getDictionaryDependencies(dictionary):
- deps = set();
- if dictionary.parent:
- deps.add(dictionary.parent)
- for member in dictionary.members:
- if member.type.isDictionary():
- deps.add(member.type.unroll().inner)
- return deps
-
-class CGRegisterProtos(CGAbstractMethod):
- def __init__(self, config):
- arguments = [
- Argument('*mut JSContext', 'cx'),
- Argument('*mut JSObject', 'global'),
- ]
- CGAbstractMethod.__init__(self, None, 'Register', 'void', arguments,
- unsafe=False, pub=True)
- self.config = config
-
- def definition_body(self):
- return CGList([
- CGGeneric("codegen::Bindings::%sBinding::DefineDOMInterface(cx, global);" % desc.name)
- for desc in self.config.getDescriptors(hasInterfaceObject=True, register=True)
- ], "\n")
-
-
-class CGRegisterProxyHandlersMethod(CGAbstractMethod):
- def __init__(self, descriptors):
- CGAbstractMethod.__init__(self, None, 'RegisterProxyHandlers', 'void', [],
- unsafe=True, pub=True)
- self.descriptors = descriptors
-
- def definition_body(self):
- return CGList([
- CGGeneric("proxy_handlers[proxies::%s as uint] = codegen::Bindings::%sBinding::DefineProxyHandler();" % (desc.name, desc.name))
- for desc in self.descriptors
- ], "\n")
-
-
-class CGRegisterProxyHandlers(CGThing):
- def __init__(self, config):
- descriptors = config.getDescriptors(proxy=True)
- length = len(descriptors)
- self.root = CGList([
- CGGeneric("pub static mut proxy_handlers: [*const libc::c_void, ..%d] = [0 as *const libc::c_void, ..%d];" % (length, length)),
- CGRegisterProxyHandlersMethod(descriptors),
- ], "\n")
-
- def define(self):
- return self.root.define()
-
-
-class CGBindingRoot(CGThing):
- """
- Root codegen class for binding generation. Instantiate the class, and call
- declare or define to generate header or cpp code (respectively).
- """
- def __init__(self, config, prefix, webIDLFile):
- descriptors = config.getDescriptors(webIDLFile=webIDLFile,
- isCallback=False)
- dictionaries = config.getDictionaries(webIDLFile=webIDLFile)
-
- cgthings = []
-
- mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile)
- callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
- isCallback=True)
-
- # Do codegen for all the enums
- cgthings = [CGEnum(e) for e in config.getEnums(webIDLFile)]
-
- cgthings.extend([CGDictionary(d, config.getDescriptorProvider())
- for d in dictionaries])
-
- # Do codegen for all the callbacks.
- cgthings.extend(CGList([CGCallbackFunction(c, config.getDescriptorProvider()),
- CGCallbackFunctionImpl(c)], "\n")
- for c in mainCallbacks)
-
- # Do codegen for all the descriptors
- cgthings.extend([CGDescriptor(x) for x in descriptors])
-
- # Do codegen for all the callback interfaces.
- cgthings.extend(CGList([CGCallbackInterface(x),
- CGCallbackFunctionImpl(x)], "\n")
- for x in callbackDescriptors)
-
- # And make sure we have the right number of newlines at the end
- curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
-
- # Wrap all of that in our namespaces.
- #curr = CGNamespace.build(['dom'],
- # CGWrapper(curr, pre="\n"))
-
- # Add imports
- #XXXjdm This should only import the namespace for the current binding,
- # not every binding ever.
- curr = CGImports(curr, descriptors, [
- 'js',
- 'js::{JS_ARGV, JS_CALLEE, JS_THIS_OBJECT}',
- 'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS}',
- 'js::{JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_SHIFT}',
- 'js::{JSCLASS_RESERVED_SLOTS_MASK, JSID_VOID, JSJitInfo}',
- 'js::{JSPROP_ENUMERATE, JSPROP_NATIVE_ACCESSORS, JSPROP_SHARED}',
- 'js::{JSRESOLVE_ASSIGNING, JSRESOLVE_QUALIFIED}',
- 'js::jsapi::{JS_CallFunctionValue, JS_GetClass, JS_GetGlobalForObject}',
- 'js::jsapi::{JS_GetObjectPrototype, JS_GetProperty, JS_GetPropertyById}',
- 'js::jsapi::{JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
- 'js::jsapi::{JS_HasProperty, JS_HasPropertyById, JS_IsExceptionPending}',
- 'js::jsapi::{JS_NewObject, JS_ObjectIsCallable, JS_SetPrototype}',
- 'js::jsapi::{JS_SetReservedSlot, JS_WrapValue, JSBool, JSContext}',
- 'js::jsapi::{JSClass, JSFreeOp, JSFunctionSpec, JSHandleObject, jsid}',
- 'js::jsapi::{JSNativeWrapper, JSObject, JSPropertyDescriptor, JS_ArrayIterator}',
- 'js::jsapi::{JSPropertyOpWrapper, JSPropertySpec, JS_PropertyStub}',
- 'js::jsapi::{JSStrictPropertyOpWrapper, JSString, JSTracer, JS_ConvertStub}',
- 'js::jsapi::{JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub}',
- 'js::jsval::JSVal',
- 'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}',
- 'js::jsval::{NullValue, UndefinedValue}',
- 'js::glue::{CallJitMethodOp, CallJitPropertyOp, CreateProxyHandler}',
- 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}',
- 'js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO}',
- 'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
- 'js::rust::with_compartment',
- 'dom::types::*',
- 'dom::bindings',
- 'dom::bindings::global::GlobalRef',
- 'dom::bindings::js::{JS, JSRef, Root, RootedReference, Temporary}',
- 'dom::bindings::js::{OptionalRootable, OptionalRootedRootable, ResultRootable}',
- 'dom::bindings::js::{OptionalRootedReference, OptionalOptionalRootedRootable}',
- 'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}',
- 'dom::bindings::utils::{ConstantSpec, cx_for_dom_object}',
- 'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}',
- 'dom::bindings::utils::{DOMJSClass, JSCLASS_DOM_GLOBAL}',
- 'dom::bindings::utils::{FindEnumStringIndex, GetArrayIndexFromId}',
- 'dom::bindings::utils::{GetPropertyOnPrototype, GetProtoOrIfaceArray}',
- 'dom::bindings::utils::{HasPropertyOnPrototype, IntVal}',
- 'dom::bindings::utils::{jsid_to_str}',
- 'dom::bindings::utils::global_object_for_js_object',
- 'dom::bindings::utils::{Reflectable}',
- 'dom::bindings::utils::{squirrel_away_unique}',
- 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}',
- 'dom::bindings::utils::VoidVal',
- 'dom::bindings::utils::get_dictionary_property',
- 'dom::bindings::utils::{NativeProperties, NativePropertyHooks}',
- 'dom::bindings::trace::JSTraceable',
- 'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
- 'dom::bindings::callback::{CallSetup,ExceptionHandling}',
- 'dom::bindings::callback::{WrapCallThisObject}',
- 'dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible}',
- 'dom::bindings::conversions::IDLInterface',
- 'dom::bindings::conversions::{Default, Empty}',
- 'dom::bindings::codegen::*',
- 'dom::bindings::codegen::Bindings::*',
- 'dom::bindings::codegen::RegisterBindings',
- 'dom::bindings::codegen::UnionTypes::*',
- 'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult}',
- 'dom::bindings::error::throw_dom_exception',
- 'dom::bindings::error::throw_type_error',
- 'dom::bindings::proxyhandler',
- 'dom::bindings::proxyhandler::{_obj_toString, defineProperty}',
- 'dom::bindings::proxyhandler::{FillPropertyDescriptor, GetExpandoObject}',
- 'dom::bindings::proxyhandler::{delete_, getPropertyDescriptor}',
- 'dom::bindings::str::ByteString',
- 'page::JSPageInfo',
- 'libc',
- 'servo_util::str::DOMString',
- 'std::mem',
- 'std::cmp',
- 'std::ptr',
- 'std::str',
- 'std::num',
- ])
-
- # Add the auto-generated comment.
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
-
- # Store the final result.
- self.root = curr
-
- def define(self):
- return stripTrailingWhitespace(self.root.define())
-
-class CGNativeMember(ClassMethod):
- def __init__(self, descriptorProvider, member, name, signature, extendedAttrs,
- breakAfter=True, passJSBitsAsNeeded=True, visibility="public",
- jsObjectsArePtr=False, variadicIsSequence=False):
- """
- If jsObjectsArePtr is true, typed arrays and "object" will be
- passed as JSObject*.
-
- If passJSBitsAsNeeded is false, we don't automatically pass in a
- JSContext* or a JSObject* based on the return and argument types.
- """
- self.descriptorProvider = descriptorProvider
- self.member = member
- self.extendedAttrs = extendedAttrs
- self.passJSBitsAsNeeded = passJSBitsAsNeeded
- self.jsObjectsArePtr = jsObjectsArePtr
- self.variadicIsSequence = variadicIsSequence
- breakAfterSelf = "\n" if breakAfter else ""
- ClassMethod.__init__(self, name,
- self.getReturnType(signature[0], False),
- self.getArgs(signature[0], signature[1]),
- static=member.isStatic(),
- # Mark our getters, which are attrs that
- # have a non-void return type, as const.
- const=(not member.isStatic() and member.isAttr() and
- not signature[0].isVoid()),
- breakAfterReturnDecl=" ",
- breakAfterSelf=breakAfterSelf,
- visibility=visibility)
-
- def getReturnType(self, type, isMember):
- return self.getRetvalInfo(type, isMember)[0]
-
- def getRetvalInfo(self, type, isMember):
- """
- Returns a tuple:
-
- The first element is the type declaration for the retval
-
- The second element is a template for actually returning a value stored in
- "${declName}". This means actually returning it if
- we're not outparam, else assigning to the "retval" outparam. If
- isMember is true, this can be None, since in that case the caller will
- never examine this value.
- """
- if type.isVoid():
- typeDecl, template = "", ""
- elif type.isPrimitive() and type.tag() in builtinNames:
- result = CGGeneric(builtinNames[type.tag()])
- if type.nullable():
- raise TypeError("Nullable primitives are not supported here.")
-
- typeDecl, template = result.define(), "return Ok(${declName});"
- elif type.isDOMString():
- if isMember:
- # No need for a third element in the isMember case
- typeDecl, template = "nsString", None
- # Outparam
- else:
- typeDecl, template = "void", "retval = ${declName};"
- elif type.isByteString():
- if isMember:
- # No need for a third element in the isMember case
- typeDecl, template = "nsCString", None
- # Outparam
- typeDecl, template = "void", "retval = ${declName};"
- elif type.isEnum():
- enumName = type.unroll().inner.identifier.name
- if type.nullable():
- enumName = CGTemplatedType("Nullable",
- CGGeneric(enumName)).define()
- typeDecl, template = enumName, "return ${declName};"
- elif type.isGeckoInterface():
- iface = type.unroll().inner;
- nativeType = self.descriptorProvider.getDescriptor(
- iface.identifier.name).nativeType
- # Now trim off unnecessary namespaces
- nativeType = nativeType.split("::")
- if nativeType[0] == "mozilla":
- nativeType.pop(0)
- if nativeType[0] == "dom":
- nativeType.pop(0)
- result = CGWrapper(CGGeneric("::".join(nativeType)), post="*")
- # Since we always force an owning type for callback return values,
- # our ${declName} is an OwningNonNull or nsRefPtr. So we can just
- # .forget() to get our already_AddRefed.
- typeDecl, template = result.define(), "return ${declName}.forget();"
- elif type.isCallback():
- typeDecl, template = \
- ("already_AddRefed<%s>" % type.unroll().identifier.name,
- "return ${declName}.forget();")
- elif type.isAny():
- typeDecl, template = "JSVal", "return Ok(${declName});"
- elif type.isObject():
- typeDecl, template = "JSObject*", "return ${declName};"
- elif type.isSpiderMonkeyInterface():
- if type.nullable():
- returnCode = "return ${declName}.IsNull() ? nullptr : ${declName}.Value().Obj();"
- else:
- returnCode = "return ${declName}.Obj();"
- typeDecl, template = "JSObject*", returnCode
- elif type.isSequence():
- # If we want to handle sequence-of-sequences return values, we're
- # going to need to fix example codegen to not produce nsTArray<void>
- # for the relevant argument...
- assert not isMember
- # Outparam.
- if type.nullable():
- returnCode = ("if (${declName}.IsNull()) {\n"
- " retval.SetNull();\n"
- "} else {\n"
- " retval.SetValue().SwapElements(${declName}.Value());\n"
- "}")
- else:
- returnCode = "retval.SwapElements(${declName});"
- typeDecl, template = "void", returnCode
- elif type.isDate():
- result = CGGeneric("Date")
- if type.nullable():
- result = CGTemplatedType("Nullable", result)
- typeDecl, template = result.define(), "return ${declName};"
- else:
- raise TypeError("Don't know how to declare return value for %s" % type)
-
- if not 'infallible' in self.extendedAttrs:
- if typeDecl:
- typeDecl = "Fallible<%s>" % typeDecl
- else:
- typeDecl = "ErrorResult"
- if not template:
- template = "return Ok(());"
- return typeDecl, template
-
- def getArgs(self, returnType, argList):
- args = [self.getArg(arg) for arg in argList]
- # Now the outparams
- if returnType.isDOMString():
- args.append(Argument("nsString&", "retval"))
- if returnType.isByteString():
- args.append(Argument("nsCString&", "retval"))
- elif returnType.isSequence():
- nullable = returnType.nullable()
- if nullable:
- returnType = returnType.inner
- # And now the actual underlying type
- elementDecl = self.getReturnType(returnType.inner, True)
- type = CGTemplatedType("nsTArray", CGGeneric(elementDecl))
- if nullable:
- type = CGTemplatedType("Nullable", type)
- args.append(Argument("%s&" % type.define(), "retval"))
- # The legacycaller thisval
- if self.member.isMethod() and self.member.isLegacycaller():
- # If it has an identifier, we can't deal with it yet
- assert self.member.isIdentifierLess()
- args.insert(0, Argument("JS::Value", "aThisVal"))
- # And jscontext bits.
- if needCx(returnType, argList, self.passJSBitsAsNeeded):
- args.insert(0, Argument("JSContext*", "cx"))
- # And if we're static, a global
- if self.member.isStatic():
- args.insert(0, Argument("const GlobalObject&", "global"))
- return args
-
- def doGetArgType(self, type, optional, isMember):
- """
- The main work of getArgType. Returns a string type decl, whether this
- is a const ref, as well as whether the type should be wrapped in
- Nullable as needed.
-
- isMember can be false or one of the strings "Sequence" or "Variadic"
- """
- if type.isArray():
- raise TypeError("Can't handle array arguments yet")
-
- if type.isSequence():
- nullable = type.nullable()
- if nullable:
- type = type.inner
- elementType = type.inner
- argType = self.getArgType(elementType, False, "Sequence")[0]
- decl = CGTemplatedType("Sequence", argType)
- return decl.define(), True, True
-
- if type.isUnion():
- if type.nullable():
- type = type.inner
- return str(type) + "::" + str(type), False, True
-
- if type.isGeckoInterface() and not type.isCallbackInterface():
- iface = type.unroll().inner
- argIsPointer = type.nullable()
- forceOwningType = iface.isCallback() or isMember
- if argIsPointer:
- if (optional or isMember) and forceOwningType:
- typeDecl = "nsRefPtr<%s>"
- else:
- typeDecl = "*%s"
- else:
- if optional or isMember:
- if forceOwningType:
- typeDecl = "OwningNonNull<%s>"
- else:
- typeDecl = "NonNull<%s>"
- else:
- typeDecl = "%s"
- descriptor = self.descriptorProvider.getDescriptor(iface.identifier.name)
- return (typeDecl % descriptor.argumentType,
- False, False)
-
- if type.isSpiderMonkeyInterface():
- if self.jsObjectsArePtr:
- return "JSObject*", False, False
-
- return type.name, True, True
-
- if type.isDOMString():
- declType = "DOMString"
- return declType, True, False
-
- if type.isByteString():
- declType = "nsCString"
- return declType, True, False
-
- if type.isEnum():
- return type.unroll().inner.identifier.name, False, True
-
- if type.isCallback() or type.isCallbackInterface():
- forceOwningType = optional or isMember
- if type.nullable():
- if forceOwningType:
- declType = "nsRefPtr<%s>"
- else:
- declType = "%s*"
- else:
- if forceOwningType:
- declType = "OwningNonNull<%s>"
- else:
- declType = "%s&"
- if type.isCallback():
- name = type.unroll().identifier.name
- else:
- name = type.unroll().inner.identifier.name
- return declType % name, False, False
-
- if type.isAny():
- # Don't do the rooting stuff for variadics for now
- if isMember:
- declType = "JS::Value"
- else:
- declType = "JSVal"
- return declType, False, False
-
- if type.isObject():
- if isMember:
- declType = "JSObject*"
- else:
- declType = "JS::Handle<JSObject*>"
- return declType, False, False
-
- if type.isDictionary():
- typeName = CGDictionary.makeDictionaryName(type.inner)
- return typeName, True, True
-
- if type.isDate():
- return "Date", False, True
-
- assert type.isPrimitive()
-
- return builtinNames[type.tag()], False, True
-
- def getArgType(self, type, optional, isMember):
- """
- Get the type of an argument declaration. Returns the type CGThing, and
- whether this should be a const ref.
-
- isMember can be False, "Sequence", or "Variadic"
- """
- (decl, ref, handleNullable) = self.doGetArgType(type, optional,
- isMember)
- decl = CGGeneric(decl)
- if handleNullable and type.nullable():
- decl = CGTemplatedType("Nullable", decl)
- ref = True
- if isMember == "Variadic":
- arrayType = "Sequence" if self.variadicIsSequence else "nsTArray"
- decl = CGTemplatedType(arrayType, decl)
- ref = True
- elif optional:
- # Note: All variadic args claim to be optional, but we can just use
- # empty arrays to represent them not being present.
- decl = CGTemplatedType("Option", decl)
- ref = False
- return (decl, ref)
-
- def getArg(self, arg):
- """
- Get the full argument declaration for an argument
- """
- (decl, ref) = self.getArgType(arg.type,
- arg.optional and not arg.defaultValue,
- "Variadic" if arg.variadic else False)
- if ref:
- decl = CGWrapper(decl, pre="&")
-
- return Argument(decl.define(), arg.identifier.name)
-
-class CGCallback(CGClass):
- def __init__(self, idlObject, descriptorProvider, baseName, methods,
- getters=[], setters=[]):
- self.baseName = baseName
- self._deps = idlObject.getDeps()
- name = idlObject.identifier.name
- # For our public methods that needThisHandling we want most of the
- # same args and the same return type as what CallbackMember
- # generates. So we want to take advantage of all its
- # CGNativeMember infrastructure, but that infrastructure can't deal
- # with templates and most especially template arguments. So just
- # cheat and have CallbackMember compute all those things for us.
- realMethods = []
- for method in methods:
- if not method.needThisHandling:
- realMethods.append(method)
- else:
- realMethods.extend(self.getMethodImpls(method))
- CGClass.__init__(self, name,
- bases=[ClassBase(baseName)],
- constructors=self.getConstructors(),
- methods=realMethods+getters+setters,
- decorators="#[deriving(PartialEq,Clone,Encodable)]")
-
- def getConstructors(self):
- return [ClassConstructor(
- [Argument("*mut JSObject", "aCallback")],
- bodyInHeader=True,
- visibility="pub",
- explicit=False,
- baseConstructors=[
- "%s::new(aCallback)" % self.baseName
- ])]
-
- def getMethodImpls(self, method):
- assert method.needThisHandling
- args = list(method.args)
- # Strip out the JSContext*/JSObject* args
- # that got added.
- assert args[0].name == "cx" and args[0].argType == "*mut JSContext"
- assert args[1].name == "aThisObj" and args[1].argType == "*mut JSObject"
- args = args[2:]
- # Record the names of all the arguments, so we can use them when we call
- # the private method.
- argnames = [arg.name for arg in args]
- argnamesWithThis = ["s.GetContext()", "thisObjJS"] + argnames
- argnamesWithoutThis = ["s.GetContext()", "ptr::mut_null()"] + argnames
- # Now that we've recorded the argnames for our call to our private
- # method, insert our optional argument for deciding whether the
- # CallSetup should re-throw exceptions on aRv.
- args.append(Argument("ExceptionHandling", "aExceptionHandling",
- "ReportExceptions"))
-
- args[0] = Argument('&' + args[0].argType, args[0].name, args[0].default)
- method.args[2] = args[0]
-
- # And now insert our template argument.
- argsWithoutThis = list(args)
- args.insert(0, Argument("&JSRef<T>", "thisObj"))
-
- # And the self argument
- method.args.insert(0, Argument(None, "&self"))
- args.insert(0, Argument(None, "&self"))
- argsWithoutThis.insert(0, Argument(None, "&self"))
-
- setupCall = ("let s = CallSetup::new(self, aExceptionHandling);\n"
- "if s.GetContext().is_null() {\n"
- " return Err(FailureUnknown);\n"
- "}\n")
-
- bodyWithThis = string.Template(
- setupCall+
- "let thisObjJS = WrapCallThisObject(s.GetContext(), thisObj);\n"
- "if thisObjJS.is_null() {\n"
- " return Err(FailureUnknown);\n"
- "}\n"
- "return ${methodName}(${callArgs});").substitute({
- "callArgs" : ", ".join(argnamesWithThis),
- "methodName": 'self.' + method.name,
- })
- bodyWithoutThis = string.Template(
- setupCall +
- "return ${methodName}(${callArgs});").substitute({
- "callArgs" : ", ".join(argnamesWithoutThis),
- "methodName": 'self.' + method.name,
- })
- return [ClassMethod(method.name+'_', method.returnType, args,
- bodyInHeader=True,
- templateArgs=["T: Reflectable"],
- body=bodyWithThis,
- visibility='pub'),
- ClassMethod(method.name+'__', method.returnType, argsWithoutThis,
- bodyInHeader=True,
- body=bodyWithoutThis,
- visibility='pub'),
- method]
-
- def deps(self):
- return self._deps
-
-# We're always fallible
-def callbackGetterName(attr):
- return "Get" + MakeNativeName(attr.identifier.name)
-
-def callbackSetterName(attr):
- return "Set" + MakeNativeName(attr.identifier.name)
-
-class CGCallbackFunction(CGCallback):
- def __init__(self, callback, descriptorProvider):
- CGCallback.__init__(self, callback, descriptorProvider,
- "CallbackFunction",
- methods=[CallCallback(callback, descriptorProvider)])
-
- def getConstructors(self):
- return CGCallback.getConstructors(self)
-
-class CGCallbackFunctionImpl(CGGeneric):
- def __init__(self, callback):
- impl = string.Template("""impl CallbackContainer for ${type} {
- fn new(callback: *mut JSObject) -> ${type} {
- ${type}::new(callback)
- }
-
- fn callback(&self) -> *mut JSObject {
- self.parent.callback()
- }
-}
-
-impl ToJSValConvertible for ${type} {
- fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
- self.callback().to_jsval(cx)
- }
-}
-""").substitute({"type": callback.name})
- CGGeneric.__init__(self, impl)
-
-class CGCallbackInterface(CGCallback):
- def __init__(self, descriptor):
- iface = descriptor.interface
- attrs = [m for m in iface.members if m.isAttr() and not m.isStatic()]
- getters = [CallbackGetter(a, descriptor) for a in attrs]
- setters = [CallbackSetter(a, descriptor) for a in attrs
- if not a.readonly]
- methods = [m for m in iface.members
- if m.isMethod() and not m.isStatic() and not m.isIdentifierLess()]
- methods = [CallbackOperation(m, sig, descriptor) for m in methods
- for sig in m.signatures()]
- assert not iface.isJSImplemented() or not iface.ctor()
- CGCallback.__init__(self, iface, descriptor, "CallbackInterface",
- methods, getters=getters, setters=setters)
-
-class FakeMember():
- def __init__(self):
- self.treatNullAs = "Default"
- def isStatic(self):
- return False
- def isAttr(self):
- return False
- def isMethod(self):
- return False
- def getExtendedAttribute(self, name):
- return None
-
-class CallbackMember(CGNativeMember):
- def __init__(self, sig, name, descriptorProvider, needThisHandling, rethrowContentException=False):
- """
- needThisHandling is True if we need to be able to accept a specified
- thisObj, False otherwise.
- """
- assert not rethrowContentException or not needThisHandling
-
- self.retvalType = sig[0]
- self.originalSig = sig
- args = sig[1]
- self.argCount = len(args)
- if self.argCount > 0:
- # Check for variadic arguments
- lastArg = args[self.argCount-1]
- if lastArg.variadic:
- self.argCountStr = (
- "(%d - 1) + %s.Length()" % (self.argCount,
- lastArg.identifier.name))
- else:
- self.argCountStr = "%d" % self.argCount
- self.needThisHandling = needThisHandling
- # If needThisHandling, we generate ourselves as private and the caller
- # will handle generating public versions that handle the "this" stuff.
- visibility = "priv" if needThisHandling else "pub"
- self.rethrowContentException = rethrowContentException
- # We don't care, for callback codegen, whether our original member was
- # a method or attribute or whatnot. Just always pass FakeMember()
- # here.
- CGNativeMember.__init__(self, descriptorProvider, FakeMember(),
- name, (self.retvalType, args),
- extendedAttrs={},
- passJSBitsAsNeeded=False,
- visibility=visibility,
- jsObjectsArePtr=True)
- # We have to do all the generation of our body now, because
- # the caller relies on us throwing if we can't manage it.
- self.exceptionCode= "return Err(FailureUnknown);\n"
- self.body = self.getImpl()
-
- def getImpl(self):
- replacements = {
- "declRval": self.getRvalDecl(),
- "returnResult": self.getResultConversion(),
- "convertArgs": self.getArgConversions(),
- "doCall": self.getCall(),
- "setupCall": self.getCallSetup(),
- }
- if self.argCount > 0:
- replacements["argCount"] = self.argCountStr
- replacements["argvDecl"] = string.Template(
- "let mut argv = Vec::from_elem(${argCount}, UndefinedValue());\n"
- ).substitute(replacements)
- else:
- # Avoid weird 0-sized arrays
- replacements["argvDecl"] = ""
-
- # Newlines and semicolons are in the values
- pre = string.Template(
- "${setupCall}"
- "${declRval}"
- "${argvDecl}").substitute(replacements)
- body = string.Template(
- "${convertArgs}"
- "${doCall}"
- "${returnResult}").substitute(replacements)
- return CGList([
- CGGeneric(pre),
- CGWrapper(CGIndenter(CGGeneric(body)),
- pre="with_compartment(cx, self.parent.callback(), || {\n",
- post="})")
- ], "\n").define()
-
- def getResultConversion(self):
- replacements = {
- "val": "rval",
- "declName": "rvalDecl",
- }
-
- template, _, declType, needsRooting = getJSToNativeConversionTemplate(
- self.retvalType,
- self.descriptorProvider,
- exceptionCode=self.exceptionCode,
- isCallbackReturnValue="Callback",
- # XXXbz we should try to do better here
- sourceDescription="return value")
-
- convertType = instantiateJSToNativeConversionTemplate(
- template, replacements, declType, "rvalDecl", needsRooting)
-
- assignRetval = string.Template(
- self.getRetvalInfo(self.retvalType,
- False)[1]).substitute(replacements)
- return convertType.define() + "\n" + assignRetval + "\n"
-
- def getArgConversions(self):
- # Just reget the arglist from self.originalSig, because our superclasses
- # just have way to many members they like to clobber, so I can't find a
- # safe member name to store it in.
- argConversions = [self.getArgConversion(i, arg) for (i, arg)
- in enumerate(self.originalSig[1])]
- # Do them back to front, so our argc modifications will work
- # correctly, because we examine trailing arguments first.
- argConversions.reverse();
- # Wrap each one in a scope so that any locals it has don't leak out, and
- # also so that we can just "break;" for our successCode.
- argConversions = [CGWrapper(CGIndenter(CGGeneric(c)),
- pre="loop {\n",
- post="\nbreak;}\n")
- for c in argConversions]
- if self.argCount > 0:
- argConversions.insert(0, self.getArgcDecl())
- # And slap them together.
- return CGList(argConversions, "\n\n").define() + "\n\n"
-
- def getArgConversion(self, i, arg):
- argval = arg.identifier.name
-
- if arg.variadic:
- argval = argval + "[idx]"
- jsvalIndex = "%d + idx" % i
- else:
- jsvalIndex = "%d" % i
- if arg.optional and not arg.defaultValue:
- argval += ".clone().unwrap()"
-
- conversion = wrapForType("*argv.get_mut(%s)" % jsvalIndex,
- result=argval,
- successCode="continue;" if arg.variadic else "break;")
- if arg.variadic:
- conversion = string.Template(
- "for (uint32_t idx = 0; idx < ${arg}.Length(); ++idx) {\n" +
- CGIndenter(CGGeneric(conversion)).define() + "\n"
- "}\n"
- "break;").substitute({ "arg": arg.identifier.name })
- elif arg.optional and not arg.defaultValue:
- conversion = (
- CGIfWrapper(CGGeneric(conversion),
- "%s.is_some()" % arg.identifier.name).define() +
- " else if (argc == %d) {\n"
- " // This is our current trailing argument; reduce argc\n"
- " argc -= 1;\n"
- "} else {\n"
- " *argv.get_mut(%d) = UndefinedValue();\n"
- "}" % (i+1, i))
- return conversion
-
- def getArgs(self, returnType, argList):
- args = CGNativeMember.getArgs(self, returnType, argList)
- if not self.needThisHandling:
- # Since we don't need this handling, we're the actual method that
- # will be called, so we need an aRethrowExceptions argument.
- if self.rethrowContentException:
- args.append(Argument("JSCompartment*", "aCompartment", "nullptr"))
- else:
- args.append(Argument("ExceptionHandling", "aExceptionHandling",
- "ReportExceptions"))
- return args
- # We want to allow the caller to pass in a "this" object, as
- # well as a JSContext.
- return [Argument("*mut JSContext", "cx"),
- Argument("*mut JSObject", "aThisObj")] + args
-
- def getCallSetup(self):
- if self.needThisHandling:
- # It's been done for us already
- return ""
- callSetup = "CallSetup s(CallbackPreserveColor(), aRv"
- if self.rethrowContentException:
- # getArgs doesn't add the aExceptionHandling argument but does add
- # aCompartment for us.
- callSetup += ", RethrowContentExceptions, aCompartment"
- else:
- callSetup += ", aExceptionHandling"
- callSetup += ");"
- return string.Template(
- "${callSetup}\n"
- "JSContext* cx = s.GetContext();\n"
- "if (!cx) {\n"
- " return Err(FailureUnknown);\n"
- "}\n").substitute({
- "callSetup": callSetup,
- })
-
- def getArgcDecl(self):
- return CGGeneric("let mut argc = %su32;" % self.argCountStr);
-
- @staticmethod
- def ensureASCIIName(idlObject):
- type = "attribute" if idlObject.isAttr() else "operation"
- if re.match("[^\x20-\x7E]", idlObject.identifier.name):
- raise SyntaxError('Callback %s name "%s" contains non-ASCII '
- "characters. We can't handle that. %s" %
- (type, idlObject.identifier.name,
- idlObject.location))
- if re.match('"', idlObject.identifier.name):
- raise SyntaxError("Callback %s name '%s' contains "
- "double-quote character. We can't handle "
- "that. %s" %
- (type, idlObject.identifier.name,
- idlObject.location))
-
-class CallbackMethod(CallbackMember):
- def __init__(self, sig, name, descriptorProvider, needThisHandling, rethrowContentException=False):
- CallbackMember.__init__(self, sig, name, descriptorProvider,
- needThisHandling, rethrowContentException)
- def getRvalDecl(self):
- return "let mut rval = UndefinedValue();\n"
-
- def getCall(self):
- replacements = {
- "thisObj": self.getThisObj(),
- "getCallable": self.getCallableDecl()
- }
- if self.argCount > 0:
- replacements["argv"] = "argv.as_mut_ptr()"
- replacements["argc"] = "argc"
- else:
- replacements["argv"] = "nullptr"
- replacements["argc"] = "0"
- return string.Template("${getCallable}"
- "let ok = unsafe {\n"
- " JS_CallFunctionValue(cx, ${thisObj}, callable,\n"
- " ${argc}, ${argv}, &mut rval)\n"
- "};\n"
- "if ok == 0 {\n"
- " return Err(FailureUnknown);\n"
- "}\n").substitute(replacements)
-
-class CallCallback(CallbackMethod):
- def __init__(self, callback, descriptorProvider):
- CallbackMethod.__init__(self, callback.signatures()[0], "Call",
- descriptorProvider, needThisHandling=True)
-
- def getThisObj(self):
- return "aThisObj"
-
- def getCallableDecl(self):
- return "let callable = ObjectValue(unsafe {&*self.parent.callback()});\n";
-
-class CallbackOperationBase(CallbackMethod):
- """
- Common class for implementing various callback operations.
- """
- def __init__(self, signature, jsName, nativeName, descriptor, singleOperation, rethrowContentException=False):
- self.singleOperation = singleOperation
- self.methodName = jsName
- CallbackMethod.__init__(self, signature, nativeName, descriptor, singleOperation, rethrowContentException)
-
- def getThisObj(self):
- if not self.singleOperation:
- return "self.parent.callback()"
- # This relies on getCallableDecl declaring a boolean
- # isCallable in the case when we're a single-operation
- # interface.
- return "if isCallable { aThisObj } else { self.parent.callback() }"
-
- def getCallableDecl(self):
- replacements = {
- "methodName": self.methodName
- }
- getCallableFromProp = string.Template(
- 'match self.parent.GetCallableProperty(cx, "${methodName}") {\n'
- ' Err(_) => return Err(FailureUnknown),\n'
- ' Ok(callable) => callable,\n'
- '}').substitute(replacements)
- if not self.singleOperation:
- return 'JS::Rooted<JS::Value> callable(cx);\n' + getCallableFromProp
- return (
- 'let isCallable = unsafe { JS_ObjectIsCallable(cx, self.parent.callback()) != 0 };\n'
- 'let callable =\n' +
- CGIndenter(
- CGIfElseWrapper('isCallable',
- CGGeneric('unsafe { ObjectValue(&*self.parent.callback()) }'),
- CGGeneric(getCallableFromProp))).define() + ';\n')
-
-class CallbackOperation(CallbackOperationBase):
- """
- Codegen actual WebIDL operations on callback interfaces.
- """
- def __init__(self, method, signature, descriptor):
- self.ensureASCIIName(method)
- jsName = method.identifier.name
- CallbackOperationBase.__init__(self, signature,
- jsName, MakeNativeName(jsName),
- descriptor, descriptor.interface.isSingleOperationInterface(),
- rethrowContentException=descriptor.interface.isJSImplemented())
-
-class CallbackGetter(CallbackMember):
- def __init__(self, attr, descriptor):
- self.ensureASCIIName(attr)
- self.attrName = attr.identifier.name
- CallbackMember.__init__(self,
- (attr.type, []),
- callbackGetterName(attr),
- descriptor,
- needThisHandling=False,
- rethrowContentException=descriptor.interface.isJSImplemented())
-
- def getRvalDecl(self):
- return "JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());\n"
-
- def getCall(self):
- replacements = {
- "attrName": self.attrName
- }
- return string.Template(
- 'if (!JS_GetProperty(cx, mCallback, "${attrName}", &rval)) {\n'
- ' return Err(FailureUnknown);\n'
- '}\n').substitute(replacements);
-
-class CallbackSetter(CallbackMember):
- def __init__(self, attr, descriptor):
- self.ensureASCIIName(attr)
- self.attrName = attr.identifier.name
- CallbackMember.__init__(self,
- (BuiltinTypes[IDLBuiltinType.Types.void],
- [FakeArgument(attr.type, attr)]),
- callbackSetterName(attr),
- descriptor,
- needThisHandling=False,
- rethrowContentException=descriptor.interface.isJSImplemented())
-
- def getRvalDecl(self):
- # We don't need an rval
- return ""
-
- def getCall(self):
- replacements = {
- "attrName": self.attrName,
- "argv": "argv.handleAt(0)",
- }
- return string.Template(
- 'MOZ_ASSERT(argv.length() == 1);\n'
- 'if (!JS_SetProperty(cx, mCallback, "${attrName}", ${argv})) {\n'
- ' return Err(FailureUnknown);\n'
- '}\n').substitute(replacements)
-
- def getArgcDecl(self):
- return None
-
-class GlobalGenRoots():
- """
- Roots for global codegen.
-
- To generate code, call the method associated with the target, and then
- call the appropriate define/declare method.
- """
-
- @staticmethod
- def PrototypeList(config):
- # Prototype ID enum.
- protos = [d.name for d in config.getDescriptors(isCallback=False)]
- proxies = [d.name for d in config.getDescriptors(proxy=True)]
-
- return CGList([
- CGGeneric(AUTOGENERATED_WARNING_COMMENT),
- CGGeneric("pub static MAX_PROTO_CHAIN_LENGTH: uint = %d;\n\n" % config.maxProtoChainLength),
- CGNamespacedEnum('id', 'ID', protos, [0], deriving="PartialEq"),
- CGNamespacedEnum('proxies', 'Proxy', proxies, [0], deriving="PartialEq"),
- ])
-
-
- @staticmethod
- def RegisterBindings(config):
- # TODO - Generate the methods we want
- code = CGList([
- CGRegisterProtos(config),
- CGRegisterProxyHandlers(config),
- ], "\n")
-
- return CGImports(code, [], [
- 'dom::bindings::codegen',
- 'dom::bindings::codegen::PrototypeList::proxies',
- 'js::jsapi::JSContext',
- 'js::jsapi::JSObject',
- 'libc',
- ])
-
- @staticmethod
- def InterfaceTypes(config):
- descriptors = [d.name for d in config.getDescriptors(register=True, isCallback=False)]
- curr = CGList([CGGeneric("pub use dom::%s::%s;\n" % (name.lower(), name)) for name in descriptors])
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
- return curr
-
- @staticmethod
- def Bindings(config):
-
- descriptors = (set(d.name + "Binding" for d in config.getDescriptors(register=True)) |
- set(d.unroll().module() for d in config.callbacks))
- curr = CGList([CGGeneric("pub mod %s;\n" % name) for name in sorted(descriptors)])
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
- return curr
-
- @staticmethod
- def InheritTypes(config):
-
- descriptors = config.getDescriptors(register=True, isCallback=False)
- allprotos = [CGGeneric("#![allow(unused_imports)]\n"),
- CGGeneric("use dom::types::*;\n"),
- CGGeneric("use dom::bindings::js::{JS, JSRef, Temporary};\n"),
- CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
- CGGeneric("use dom::bindings::utils::Reflectable;\n"),
- CGGeneric("use serialize::{Encodable, Encoder};\n"),
- CGGeneric("use js::jsapi::JSTracer;\n\n")]
- for descriptor in descriptors:
- name = descriptor.name
- protos = [CGGeneric('pub trait %s {}\n' % (name + 'Base'))]
- for proto in descriptor.prototypeChain:
- protos += [CGGeneric('impl %s for %s {}\n' % (proto + 'Base',
- descriptor.concreteType))]
- derived = [CGGeneric('pub trait %s { fn %s(&self) -> bool; }\n' %
- (name + 'Derived', 'is_' + name.lower()))]
- for protoName in descriptor.prototypeChain[1:-1]:
- protoDescriptor = config.getDescriptor(protoName)
- delegate = string.Template('''impl ${selfName} for ${baseName} {
- fn ${fname}(&self) -> bool {
- self.${parentName}.${fname}()
- }
-}
-''').substitute({'fname': 'is_' + name.lower(),
- 'selfName': name + 'Derived',
- 'baseName': protoDescriptor.concreteType,
- 'parentName': protoDescriptor.prototypeChain[-2].lower()})
- derived += [CGGeneric(delegate)]
- derived += [CGGeneric('\n')]
-
- cast = [CGGeneric(string.Template('''pub trait ${castTraitName} {
- #[inline(always)]
- fn to_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a JSRef<'b, T>) -> Option<&'a JSRef<'b, Self>> {
- match base.deref().${checkFn}() {
- true => unsafe { Some(base.transmute()) },
- false => None
- }
- }
-
- #[inline(always)]
- fn to_mut_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a mut JSRef<'b, T>) -> Option<&'a mut JSRef<'b, Self>> {
- match base.deref().${checkFn}() {
- true => unsafe { Some(base.transmute_mut()) },
- false => None
- }
- }
-
- #[inline(always)]
- fn from_ref<'a, 'b, T: ${fromBound}>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, Self> {
- unsafe { derived.transmute() }
- }
-
- #[inline(always)]
- fn from_mut_ref<'a, 'b, T: ${fromBound}>(derived: &'a mut JSRef<'b, T>) -> &'a mut JSRef<'b, Self> {
- unsafe { derived.transmute_mut() }
- }
-
- #[inline(always)]
- fn from_temporary<T: ${fromBound}+Reflectable>(derived: Temporary<T>) -> Temporary<Self> {
- unsafe { derived.transmute() }
- }
-}
-''').substitute({'checkFn': 'is_' + name.lower(),
- 'castTraitName': name + 'Cast',
- 'fromBound': name + 'Base',
- 'toBound': name + 'Derived'})),
- CGGeneric("impl %s for %s {}\n\n" % (name + 'Cast', name))]
-
- trace = [CGGeneric(string.Template('''impl JSTraceable for ${name} {
- fn trace(&self, tracer: *mut JSTracer) {
- unsafe {
- self.encode(&mut *tracer).ok().expect("failed to encode");
- }
- }
-}
-''').substitute({'name': name}))]
-
- allprotos += protos + derived + cast + trace
-
- curr = CGList(allprotos)
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
- return curr
-
- @staticmethod
- def UnionTypes(config):
-
- curr = UnionTypes(config.getDescriptors(),
- config.getDictionaries(),
- config.getCallbacks(),
- config)
-
- # Add the auto-generated comment.
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
-
- # Done.
- return curr
diff --git a/src/components/script/dom/bindings/codegen/Configuration.py b/src/components/script/dom/bindings/codegen/Configuration.py
deleted file mode 100644
index d9be43fd2e6..00000000000
--- a/src/components/script/dom/bindings/codegen/Configuration.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# 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/.
-
-from WebIDL import IDLInterface
-
-autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
-
-class Configuration:
- """
- Represents global configuration state based on IDL parse data and
- the configuration file.
- """
- def __init__(self, filename, parseData):
- # Read the configuration file.
- glbl = {}
- execfile(filename, glbl)
- config = glbl['DOMInterfaces']
-
- # Build descriptors for all the interfaces we have in the parse data.
- # This allows callers to specify a subset of interfaces by filtering
- # |parseData|.
- self.descriptors = []
- self.interfaces = {}
- self.maxProtoChainLength = 0;
- for thing in parseData:
- # Some toplevel things are sadly types, and those have an
- # isInterface that doesn't mean the same thing as IDLObject's
- # isInterface()...
- if not isinstance(thing, IDLInterface):
- continue
-
- iface = thing
- self.interfaces[iface.identifier.name] = iface
- if iface.identifier.name not in config:
- # Completely skip consequential interfaces with no descriptor
- # if they have no interface object because chances are we
- # don't need to do anything interesting with them.
- if iface.isConsequential() and not iface.hasInterfaceObject():
- continue
- entry = {}
- else:
- entry = config[iface.identifier.name]
- if not isinstance(entry, list):
- assert isinstance(entry, dict)
- entry = [entry]
- self.descriptors.extend([Descriptor(self, iface, x) for x in entry])
-
- # Mark the descriptors for which only a single nativeType implements
- # an interface.
- for descriptor in self.descriptors:
- intefaceName = descriptor.interface.identifier.name
- otherDescriptors = [d for d in self.descriptors
- if d.interface.identifier.name == intefaceName]
- descriptor.uniqueImplementation = len(otherDescriptors) == 1
-
- self.enums = [e for e in parseData if e.isEnum()]
- self.dictionaries = [d for d in parseData if d.isDictionary()]
- self.callbacks = [c for c in parseData if
- c.isCallback() and not c.isInterface()]
-
- # Keep the descriptor list sorted for determinism.
- self.descriptors.sort(lambda x,y: cmp(x.name, y.name))
-
- def getInterface(self, ifname):
- return self.interfaces[ifname]
- def getDescriptors(self, **filters):
- """Gets the descriptors that match the given filters."""
- curr = self.descriptors
- for key, val in filters.iteritems():
- if key == 'webIDLFile':
- getter = lambda x: x.interface.filename()
- elif key == 'hasInterfaceObject':
- getter = lambda x: x.interface.hasInterfaceObject()
- elif key == 'isCallback':
- getter = lambda x: x.interface.isCallback()
- elif key == 'isJSImplemented':
- getter = lambda x: x.interface.isJSImplemented()
- else:
- getter = lambda x: getattr(x, key)
- curr = filter(lambda x: getter(x) == val, curr)
- return curr
- def getEnums(self, webIDLFile):
- return filter(lambda e: e.filename() == webIDLFile, self.enums)
-
- @staticmethod
- def _filterForFile(items, webIDLFile=""):
- """Gets the items that match the given filters."""
- if not webIDLFile:
- return items
-
- return filter(lambda x: x.filename() == webIDLFile, items)
-
- def getDictionaries(self, webIDLFile=""):
- return self._filterForFile(self.dictionaries, webIDLFile=webIDLFile)
- def getCallbacks(self, webIDLFile=""):
- return self._filterForFile(self.callbacks, webIDLFile=webIDLFile)
-
- def getDescriptor(self, interfaceName):
- """
- Gets the appropriate descriptor for the given interface name.
- """
- iface = self.getInterface(interfaceName)
- descriptors = self.getDescriptors(interface=iface)
-
- # We should have exactly one result.
- if len(descriptors) is not 1:
- raise NoSuchDescriptorError("For " + interfaceName + " found " +
- str(len(matches)) + " matches");
- return descriptors[0]
- def getDescriptorProvider(self):
- """
- Gets a descriptor provider that can provide descriptors as needed.
- """
- return DescriptorProvider(self)
-
-class NoSuchDescriptorError(TypeError):
- def __init__(self, str):
- TypeError.__init__(self, str)
-
-class DescriptorProvider:
- """
- A way of getting descriptors for interface names
- """
- def __init__(self, config):
- self.config = config
-
- def getDescriptor(self, interfaceName):
- """
- Gets the appropriate descriptor for the given interface name given the
- context of the current descriptor.
- """
- return self.config.getDescriptor(interfaceName)
-
-class Descriptor(DescriptorProvider):
- """
- Represents a single descriptor for an interface. See Bindings.conf.
- """
- def __init__(self, config, interface, desc):
- DescriptorProvider.__init__(self, config)
- self.interface = interface
-
- # Read the desc, and fill in the relevant defaults.
- ifaceName = self.interface.identifier.name
-
- # Callback types do not use JS smart pointers, so we should not use the
- # built-in rooting mechanisms for them.
- if self.interface.isCallback():
- self.needsRooting = False
- else:
- self.needsRooting = True
-
- self.returnType = desc.get('returnType', "Temporary<%s>" % ifaceName)
- self.argumentType = "JSRef<%s>" % ifaceName
- self.memberType = "Root<'a, 'b, %s>" % ifaceName
- self.nativeType = desc.get('nativeType', 'JS<%s>' % ifaceName)
- self.concreteType = desc.get('concreteType', ifaceName)
- self.register = desc.get('register', True)
- self.outerObjectHook = desc.get('outerObjectHook', 'None')
-
- # If we're concrete, we need to crawl our ancestor interfaces and mark
- # them as having a concrete descendant.
- self.concrete = desc.get('concrete', True)
- if self.concrete:
- self.proxy = False
- operations = {
- 'IndexedGetter': None,
- 'IndexedSetter': None,
- 'IndexedCreator': None,
- 'IndexedDeleter': None,
- 'NamedGetter': None,
- 'NamedSetter': None,
- 'NamedCreator': None,
- 'NamedDeleter': None,
- 'Stringifier': None
- }
- iface = self.interface
- while iface:
- for m in iface.members:
- if not m.isMethod():
- continue
-
- def addOperation(operation, m):
- if not operations[operation]:
- operations[operation] = m
- def addIndexedOrNamedOperation(operation, m):
- self.proxy = True
- if m.isIndexed():
- operation = 'Indexed' + operation
- else:
- assert m.isNamed()
- operation = 'Named' + operation
- addOperation(operation, m)
-
- if m.isStringifier():
- addOperation('Stringifier', m)
- else:
- if m.isGetter():
- addIndexedOrNamedOperation('Getter', m)
- if m.isSetter():
- addIndexedOrNamedOperation('Setter', m)
- if m.isCreator():
- addIndexedOrNamedOperation('Creator', m)
- if m.isDeleter():
- addIndexedOrNamedOperation('Deleter', m)
- raise TypeError("deleter specified on %s but we "
- "don't support deleters yet" %
- self.interface.identifier.name)
-
- iface.setUserData('hasConcreteDescendant', True)
- iface = iface.parent
-
- if self.proxy:
- self.operations = operations
- iface = self.interface
- while iface:
- iface.setUserData('hasProxyDescendant', True)
- iface = iface.parent
-
- self.name = interface.identifier.name
-
- # self.extendedAttributes is a dict of dicts, keyed on
- # all/getterOnly/setterOnly and then on member name. Values are an
- # array of extended attributes.
- self.extendedAttributes = { 'all': {}, 'getterOnly': {}, 'setterOnly': {} }
-
- def addExtendedAttribute(attribute, config):
- def add(key, members, attribute):
- for member in members:
- self.extendedAttributes[key].setdefault(member, []).append(attribute)
-
- if isinstance(config, dict):
- for key in ['all', 'getterOnly', 'setterOnly']:
- add(key, config.get(key, []), attribute)
- elif isinstance(config, list):
- add('all', config, attribute)
- else:
- assert isinstance(config, str)
- if config == '*':
- iface = self.interface
- while iface:
- add('all', map(lambda m: m.name, iface.members), attribute)
- iface = iface.parent
- else:
- add('all', [config], attribute)
-
- # Build the prototype chain.
- self.prototypeChain = []
- parent = interface
- while parent:
- self.prototypeChain.insert(0, parent.identifier.name)
- parent = parent.parent
- config.maxProtoChainLength = max(config.maxProtoChainLength,
- len(self.prototypeChain))
-
- def getExtendedAttributes(self, member, getter=False, setter=False):
- def maybeAppendInfallibleToAttrs(attrs, throws):
- if throws is None:
- attrs.append("infallible")
- elif throws is True:
- pass
- else:
- raise TypeError("Unknown value for 'Throws'")
-
- name = member.identifier.name
- if member.isMethod():
- attrs = self.extendedAttributes['all'].get(name, [])
- throws = member.getExtendedAttribute("Throws")
- maybeAppendInfallibleToAttrs(attrs, throws)
- return attrs
-
- assert member.isAttr()
- assert bool(getter) != bool(setter)
- key = 'getterOnly' if getter else 'setterOnly'
- attrs = self.extendedAttributes['all'].get(name, []) + self.extendedAttributes[key].get(name, [])
- throws = member.getExtendedAttribute("Throws")
- if throws is None:
- throwsAttr = "GetterThrows" if getter else "SetterThrows"
- throws = member.getExtendedAttribute(throwsAttr)
- maybeAppendInfallibleToAttrs(attrs, throws)
- return attrs
-
- def isGlobal(self):
- """
- Returns true if this is the primary interface for a global object
- of some sort.
- """
- return (self.interface.getExtendedAttribute("Global") or
- self.interface.getExtendedAttribute("PrimaryGlobal"))
-
-
-# Some utility methods
-def getTypesFromDescriptor(descriptor):
- """
- Get all argument and return types for all members of the descriptor
- """
- members = [m for m in descriptor.interface.members]
- if descriptor.interface.ctor():
- members.append(descriptor.interface.ctor())
- members.extend(descriptor.interface.namedConstructors)
- signatures = [s for m in members if m.isMethod() for s in m.signatures()]
- types = []
- for s in signatures:
- assert len(s) == 2
- (returnType, arguments) = s
- types.append(returnType)
- types.extend(a.type for a in arguments)
-
- types.extend(a.type for a in members if a.isAttr())
- return types
-
-def getFlatTypes(types):
- retval = set()
- for type in types:
- type = type.unroll()
- if type.isUnion():
- retval |= set(type.flatMemberTypes)
- else:
- retval.add(type)
- return retval
-
-def getTypesFromDictionary(dictionary):
- """
- Get all member types for this dictionary
- """
- types = []
- curDict = dictionary
- while curDict:
- types.extend([m.type for m in curDict.members])
- curDict = curDict.parent
- return types
-
-def getTypesFromCallback(callback):
- """
- Get the types this callback depends on: its return type and the
- types of its arguments.
- """
- sig = callback.signatures()[0]
- types = [sig[0]] # Return type
- types.extend(arg.type for arg in sig[1]) # Arguments
- return types
diff --git a/src/components/script/dom/bindings/codegen/DOMJSClass.h b/src/components/script/dom/bindings/codegen/DOMJSClass.h
deleted file mode 100644
index 151960b5901..00000000000
--- a/src/components/script/dom/bindings/codegen/DOMJSClass.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* 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/. */
-
-#ifndef mozilla_dom_DOMJSClass_h
-#define mozilla_dom_DOMJSClass_h
-
-#include "jsapi.h"
-#include "jsfriendapi.h"
-
-#include "mozilla/dom/PrototypeList.h" // auto-generated
-
-// We use slot 0 for holding the raw object. This is safe for both
-// globals and non-globals.
-#define DOM_OBJECT_SLOT 0
-
-// All DOM globals must have a slot at DOM_PROTOTYPE_SLOT. We have to
-// start at 1 past JSCLASS_GLOBAL_SLOT_COUNT because XPConnect uses
-// that one.
-#define DOM_PROTOTYPE_SLOT (JSCLASS_GLOBAL_SLOT_COUNT + 1)
-
-// We use these flag bits for the new bindings.
-#define JSCLASS_DOM_GLOBAL JSCLASS_USERBIT1
-
-// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
-// LSetDOMProperty. Those constants need to be changed accordingly if this value
-// changes.
-#define DOM_PROTO_INSTANCE_CLASS_SLOT 0
-
-namespace mozilla {
-namespace dom {
-
-typedef bool
-(* ResolveProperty)(JSContext* cx, JSObject* wrapper, jsid id, bool set,
- JSPropertyDescriptor* desc);
-typedef bool
-(* EnumerateProperties)(JSContext* cx, JSObject* wrapper,
- JS::AutoIdVector& props);
-
-struct NativePropertyHooks
-{
- ResolveProperty mResolveOwnProperty;
- ResolveProperty mResolveProperty;
- EnumerateProperties mEnumerateOwnProperties;
- EnumerateProperties mEnumerateProperties;
-
- const NativePropertyHooks *mProtoHooks;
-};
-
-struct DOMClass
-{
- // A list of interfaces that this object implements, in order of decreasing
- // derivedness.
- const prototypes::ID mInterfaceChain[prototypes::id::_ID_Count];
-
- // We store the DOM object in reserved slot with index DOM_OBJECT_SLOT or in
- // the proxy private if we use a proxy object.
- // Sometimes it's an nsISupports and sometimes it's not; this class tells
- // us which it is.
- const bool mDOMObjectIsISupports;
-
- const NativePropertyHooks* mNativeHooks;
-};
-
-// Special JSClass for reflected DOM objects.
-struct DOMJSClass
-{
- // It would be nice to just inherit from JSClass, but that precludes pure
- // compile-time initialization of the form |DOMJSClass = {...};|, since C++
- // only allows brace initialization for aggregate/POD types.
- JSClass mBase;
-
- DOMClass mClass;
-
- static DOMJSClass* FromJSClass(JSClass* base) {
- MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
- return reinterpret_cast<DOMJSClass*>(base);
- }
- static const DOMJSClass* FromJSClass(const JSClass* base) {
- MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
- return reinterpret_cast<const DOMJSClass*>(base);
- }
-
- static DOMJSClass* FromJSClass(js::Class* base) {
- return FromJSClass(Jsvalify(base));
- }
- static const DOMJSClass* FromJSClass(const js::Class* base) {
- return FromJSClass(Jsvalify(base));
- }
-
- JSClass* ToJSClass() { return &mBase; }
-};
-
-inline bool
-HasProtoOrIfaceArray(JSObject* global)
-{
- MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
- // This can be undefined if we GC while creating the global
- return !js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).isUndefined();
-}
-
-inline JSObject**
-GetProtoOrIfaceArray(JSObject* global)
-{
- MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
- return static_cast<JSObject**>(
- js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).toPrivate());
-}
-
-} // namespace dom
-} // namespace mozilla
-
-#endif /* mozilla_dom_DOMJSClass_h */
diff --git a/src/components/script/dom/bindings/codegen/DOMJSProxyHandler.cpp b/src/components/script/dom/bindings/codegen/DOMJSProxyHandler.cpp
deleted file mode 100644
index af45cc6ed1a..00000000000
--- a/src/components/script/dom/bindings/codegen/DOMJSProxyHandler.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: set ts=2 sw=2 et tw=99 ft=cpp: */
-/* 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/. */
-
-#include "mozilla/Util.h"
-
-#include "DOMJSProxyHandler.h"
-#include "xpcpublic.h"
-#include "xpcprivate.h"
-#include "XPCQuickStubs.h"
-#include "XPCWrapper.h"
-#include "WrapperFactory.h"
-#include "nsDOMClassInfo.h"
-#include "nsGlobalWindow.h"
-#include "nsWrapperCacheInlines.h"
-#include "mozilla/dom/BindingUtils.h"
-
-#include "jsapi.h"
-
-using namespace JS;
-
-namespace mozilla {
-namespace dom {
-
-jsid s_length_id = JSID_VOID;
-
-bool
-DefineStaticJSVals(JSContext* cx)
-{
- JSAutoRequest ar(cx);
-
- return InternJSString(cx, s_length_id, "length");
-}
-
-
-int HandlerFamily;
-
-// Store the information for the specialized ICs.
-struct SetListBaseInformation
-{
- SetListBaseInformation() {
- js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO);
- }
-};
-
-SetListBaseInformation gSetListBaseInformation;
-
-
-bool
-DefineConstructor(JSContext* cx, JSObject* obj, DefineInterface aDefine, nsresult* aResult)
-{
- bool enabled;
- bool defined = aDefine(cx, obj, &enabled);
- MOZ_ASSERT(!defined || enabled,
- "We defined a constructor but the new bindings are disabled?");
- *aResult = defined ? NS_OK : NS_ERROR_FAILURE;
- return enabled;
-}
-
-// static
-JSObject*
-DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JSObject* obj)
-{
- NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
- JSObject* expando = GetExpandoObject(obj);
- if (!expando) {
- expando = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
- js::GetObjectParent(obj));
- if (!expando) {
- return NULL;
- }
-
- xpc::CompartmentPrivate* priv = xpc::GetCompartmentPrivate(obj);
- if (!priv->RegisterDOMExpandoObject(obj)) {
- return NULL;
- }
-
- nsWrapperCache* cache;
- CallQueryInterface(UnwrapDOMObject<nsISupports>(obj, eProxyDOMObject), &cache);
- cache->SetPreservingWrapper(true);
-
- js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
- }
- return expando;
-}
-
-bool
-DOMProxyHandler::getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set,
- JSPropertyDescriptor* desc)
-{
- if (!getOwnPropertyDescriptor(cx, proxy, id, set, desc)) {
- return false;
- }
- if (desc->obj) {
- return true;
- }
-
- JSObject* proto;
- if (!js::GetObjectProto(cx, proxy, &proto)) {
- return false;
- }
- if (!proto) {
- desc->obj = NULL;
- return true;
- }
-
- return JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc);
-}
-
-bool
-DOMProxyHandler::defineProperty(JSContext* cx, JSObject* proxy, jsid id,
- JSPropertyDescriptor* desc)
-{
- if ((desc->attrs & JSPROP_GETTER) && desc->setter == JS_StrictPropertyStub) {
- return JS_ReportErrorFlagsAndNumber(cx,
- JSREPORT_WARNING | JSREPORT_STRICT |
- JSREPORT_STRICT_MODE_ERROR,
- js_GetErrorMessage, NULL,
- JSMSG_GETTER_ONLY);
- }
-
- if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
- return true;
- }
-
- JSObject* expando = EnsureExpandoObject(cx, proxy);
- if (!expando) {
- return false;
- }
-
- return JS_DefinePropertyById(cx, expando, id, desc->value, desc->getter, desc->setter,
- desc->attrs);
-}
-
-bool
-DOMProxyHandler::delete_(JSContext* cx, JSObject* proxy, jsid id, bool* bp)
-{
- JSBool b = true;
-
- JSObject* expando;
- if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
- Value v;
- if (!JS_DeletePropertyById2(cx, expando, id, &v) || !JS_ValueToBoolean(cx, v, &b)) {
- return false;
- }
- }
-
- *bp = !!b;
- return true;
-}
-
-bool
-DOMProxyHandler::enumerate(JSContext* cx, JSObject* proxy, AutoIdVector& props)
-{
- JSObject* proto;
- if (!JS_GetPrototype(cx, proxy, &proto)) {
- return false;
- }
- return getOwnPropertyNames(cx, proxy, props) &&
- (!proto || js::GetPropertyNames(cx, proto, 0, &props));
-}
-
-bool
-DOMProxyHandler::fix(JSContext* cx, JSObject* proxy, Value* vp)
-{
- vp->setUndefined();
- return true;
-}
-
-bool
-DOMProxyHandler::has(JSContext* cx, JSObject* proxy, jsid id, bool* bp)
-{
- if (!hasOwn(cx, proxy, id, bp)) {
- return false;
- }
-
- if (*bp) {
- // We have the property ourselves; no need to worry about our prototype
- // chain.
- return true;
- }
-
- // OK, now we have to look at the proto
- JSObject *proto;
- if (!js::GetObjectProto(cx, proxy, &proto)) {
- return false;
- }
- if (!proto) {
- return true;
- }
- JSBool protoHasProp;
- bool ok = JS_HasPropertyById(cx, proto, id, &protoHasProp);
- if (ok) {
- *bp = protoHasProp;
- }
- return ok;
-}
-
-// static
-JSString*
-DOMProxyHandler::obj_toString(JSContext* cx, const char* className)
-{
- size_t nchars = sizeof("[object ]") - 1 + strlen(className);
- jschar* chars = static_cast<jschar*>(JS_malloc(cx, (nchars + 1) * sizeof(jschar)));
- if (!chars) {
- return NULL;
- }
-
- const char* prefix = "[object ";
- nchars = 0;
- while ((chars[nchars] = (jschar)*prefix) != 0) {
- nchars++, prefix++;
- }
- while ((chars[nchars] = (jschar)*className) != 0) {
- nchars++, className++;
- }
- chars[nchars++] = ']';
- chars[nchars] = 0;
-
- JSString* str = JS_NewUCString(cx, chars, nchars);
- if (!str) {
- JS_free(cx, chars);
- }
- return str;
-}
-
-int32_t
-IdToInt32(JSContext* cx, jsid id)
-{
- JSAutoRequest ar(cx);
-
- jsval idval;
- double array_index;
- int32_t i;
- if (!::JS_IdToValue(cx, id, &idval) ||
- !::JS_ValueToNumber(cx, idval, &array_index) ||
- !::JS_DoubleIsInt32(array_index, &i)) {
- return -1;
- }
-
- return i;
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/src/components/script/dom/bindings/codegen/DOMJSProxyHandler.h b/src/components/script/dom/bindings/codegen/DOMJSProxyHandler.h
deleted file mode 100644
index 394e2dc4d2f..00000000000
--- a/src/components/script/dom/bindings/codegen/DOMJSProxyHandler.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* 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/. */
-
-#ifndef mozilla_dom_DOMJSProxyHandler_h
-#define mozilla_dom_DOMJSProxyHandler_h
-
-#include "jsapi.h"
-#include "jsfriendapi.h"
-#include "jsproxy.h"
-#include "xpcpublic.h"
-#include "nsString.h"
-#include "mozilla/Likely.h"
-
-#define DOM_PROXY_OBJECT_SLOT js::JSSLOT_PROXY_PRIVATE
-
-namespace mozilla {
-namespace dom {
-
-enum {
- JSPROXYSLOT_EXPANDO = 0
-};
-
-template<typename T> struct Prefable;
-
-class DOMProxyHandler : public DOMBaseProxyHandler
-{
-public:
- DOMProxyHandler(const DOMClass& aClass)
- : DOMBaseProxyHandler(true),
- mClass(aClass)
- {
- }
-
- bool getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set,
- JSPropertyDescriptor* desc);
- bool defineProperty(JSContext* cx, JSObject* proxy, jsid id,
- JSPropertyDescriptor* desc);
- bool delete_(JSContext* cx, JSObject* proxy, jsid id, bool* bp);
- bool enumerate(JSContext* cx, JSObject* proxy, JS::AutoIdVector& props);
- bool fix(JSContext* cx, JSObject* proxy, JS::Value* vp);
- bool has(JSContext* cx, JSObject* proxy, jsid id, bool* bp);
- using js::BaseProxyHandler::obj_toString;
-
- static JSObject* GetExpandoObject(JSObject* obj)
- {
- MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
- JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
- return v.isUndefined() ? NULL : v.toObjectOrNull();
- }
- static JSObject* EnsureExpandoObject(JSContext* cx, JSObject* obj);
-
- const DOMClass& mClass;
-
-protected:
- static JSString* obj_toString(JSContext* cx, const char* className);
-};
-
-extern jsid s_length_id;
-
-int32_t IdToInt32(JSContext* cx, jsid id);
-
-inline int32_t
-GetArrayIndexFromId(JSContext* cx, jsid id)
-{
- if (MOZ_LIKELY(JSID_IS_INT(id))) {
- return JSID_TO_INT(id);
- }
- if (MOZ_LIKELY(id == s_length_id)) {
- return -1;
- }
- if (MOZ_LIKELY(JSID_IS_ATOM(id))) {
- JSAtom* atom = JSID_TO_ATOM(id);
- jschar s = *js::GetAtomChars(atom);
- if (MOZ_LIKELY((unsigned)s >= 'a' && (unsigned)s <= 'z'))
- return -1;
-
- uint32_t i;
- JSLinearString* str = js::AtomToLinearString(JSID_TO_ATOM(id));
- return js::StringIsArrayIndex(str, &i) ? i : -1;
- }
- return IdToInt32(cx, id);
-}
-
-inline void
-FillPropertyDescriptor(JSPropertyDescriptor* desc, JSObject* obj, bool readonly)
-{
- desc->obj = obj;
- desc->attrs = (readonly ? JSPROP_READONLY : 0) | JSPROP_ENUMERATE;
- desc->getter = NULL;
- desc->setter = NULL;
- desc->shortid = 0;
-}
-
-inline void
-FillPropertyDescriptor(JSPropertyDescriptor* desc, JSObject* obj, jsval v, bool readonly)
-{
- desc->value = v;
- FillPropertyDescriptor(desc, obj, readonly);
-}
-
-JSObject*
-EnsureExpandoObject(JSContext* cx, JSObject* obj);
-
-} // namespace dom
-} // namespace mozilla
-
-#endif /* mozilla_dom_DOMProxyHandler_h */
diff --git a/src/components/script/dom/bindings/codegen/ErrorResult.h b/src/components/script/dom/bindings/codegen/ErrorResult.h
deleted file mode 100644
index bbd9404a865..00000000000
--- a/src/components/script/dom/bindings/codegen/ErrorResult.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
-/* 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/. */
-
-/**
- * A struct for tracking exceptions that need to be thrown to JS.
- */
-
-#ifndef mozilla_ErrorResult_h
-#define mozilla_ErrorResult_h
-
-#include "nscore.h"
-#include "mozilla/Assertions.h"
-
-namespace mozilla {
-
-class ErrorResult {
-public:
- ErrorResult() {
- mResult = NS_OK;
- }
-
- void Throw(nsresult rv) {
- MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
- mResult = rv;
- }
-
- // In the future, we can add overloads of Throw that take more
- // interesting things, like strings or DOM exception types or
- // something if desired.
-
- // Backwards-compat to make conversion simpler. We don't call
- // Throw() here because people can easily pass success codes to
- // this.
- void operator=(nsresult rv) {
- mResult = rv;
- }
-
- bool Failed() const {
- return NS_FAILED(mResult);
- }
-
- nsresult ErrorCode() const {
- return mResult;
- }
-
-private:
- nsresult mResult;
-
- // Not to be implemented, to make sure people always pass this by
- // reference, not by value.
- ErrorResult(const ErrorResult&) MOZ_DELETE;
-};
-
-} // namespace mozilla
-
-#endif /* mozilla_ErrorResult_h */
diff --git a/src/components/script/dom/bindings/codegen/Errors.msg b/src/components/script/dom/bindings/codegen/Errors.msg
deleted file mode 100644
index 81d6624cec8..00000000000
--- a/src/components/script/dom/bindings/codegen/Errors.msg
+++ /dev/null
@@ -1,30 +0,0 @@
-/* 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/. */
-
-/*
- * The format for each error message is:
- *
- * MSG_DEF(<SYMBOLIC_NAME>, <ARGUMENT_COUNT>, <FORMAT_STRING>)
- *
- * where
- *
- * <SYMBOLIC_NAME> is a legal C++ identifer that will be used in the source.
- *
- * <ARGUMENT_COUNT> is an integer literal specifying the total number of
- * replaceable arguments in the following format string.
- *
- * <FORMAT_STRING> is a string literal, containing <ARGUMENT_COUNT> sequences
- * {X} where X is an integer representing the argument number that will
- * be replaced with a string value when the error is reported.
- */
-
-MSG_DEF(MSG_INVALID_ENUM_VALUE, 2, "Value '{0}' is not a valid value for enumeration {1}.")
-MSG_DEF(MSG_MISSING_ARGUMENTS, 1, "Not enough arguments to {0}.")
-MSG_DEF(MSG_NOT_OBJECT, 0, "Value not an object.")
-MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 1, "Value does not implement interface {0}.")
-MSG_DEF(MSG_NOT_IN_UNION, 1, "Value could not be converted to any of: {0}.")
-MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.")
-MSG_DEF(MSG_NO_PROPERTY_SETTER, 1, "{0} doesn't have an indexed property setter.")
-MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, "Non-finite value is out of range for {0}.")
-MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, "Value is out of range for {0}.")
diff --git a/src/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py b/src/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py
deleted file mode 100644
index 1bb50afaee7..00000000000
--- a/src/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# 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 sys
-import string
-
-propList = eval(sys.stdin.read())
-props = ""
-for [prop, pref] in propList:
- extendedAttrs = ["Throws", "TreatNullAs=EmptyString"]
- if pref is not "":
- extendedAttrs.append("Pref=%s" % pref)
- if not prop.startswith("Moz"):
- prop = prop[0].lower() + prop[1:]
- # Unfortunately, even some of the getters here are fallible
- # (e.g. on nsComputedDOMStyle).
- props += " [%s] attribute DOMString %s;\n" % (", ".join(extendedAttrs),
- prop)
-
-idlFile = open(sys.argv[1], "r");
-idlTemplate = idlFile.read();
-idlFile.close();
-
-print ("/* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT */\n\n" +
- string.Template(idlTemplate).substitute({ "props": props }))
diff --git a/src/components/script/dom/bindings/codegen/GlobalGen.py b/src/components/script/dom/bindings/codegen/GlobalGen.py
deleted file mode 100644
index cdca464e029..00000000000
--- a/src/components/script/dom/bindings/codegen/GlobalGen.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# 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/.
-
-# We do one global pass over all the WebIDL to generate our prototype enum
-# and generate information for subsequent phases.
-
-import sys
-sys.path.append("./parser/")
-sys.path.append("./ply/")
-import os
-import cStringIO
-import WebIDL
-import cPickle
-from Configuration import *
-from CodegenRust import GlobalGenRoots, replaceFileIfChanged
-# import Codegen in general, so we can set a variable on it
-import Codegen
-
-def generate_file(config, name, filename):
- root = getattr(GlobalGenRoots, name)(config)
- code = root.define()
-
- if replaceFileIfChanged(filename, code):
- print "Generating %s" % (filename)
- else:
- print "%s hasn't changed - not touching it" % (filename)
-
-def main():
- # Parse arguments.
- from optparse import OptionParser
- usageString = "usage: %prog [options] webidldir [files]"
- o = OptionParser(usage=usageString)
- o.add_option("--cachedir", dest='cachedir', default=None,
- help="Directory in which to cache lex/parse tables.")
- o.add_option("--verbose-errors", action='store_true', default=False,
- help="When an error happens, display the Python traceback.")
- (options, args) = o.parse_args()
-
- if len(args) < 2:
- o.error(usageString)
-
- configFile = args[0]
- baseDir = args[1]
- fileList = args[2:]
-
- # Parse the WebIDL.
- parser = WebIDL.Parser(options.cachedir)
- for filename in fileList:
- fullPath = os.path.normpath(os.path.join(baseDir, filename))
- f = open(fullPath, 'rb')
- lines = f.readlines()
- f.close()
- parser.parse(''.join(lines), fullPath)
- parserResults = parser.finish()
-
- # Write the parser results out to a pickle.
- resultsFile = open('ParserResults.pkl', 'wb')
- cPickle.dump(parserResults, resultsFile, -1)
- resultsFile.close()
-
- # Load the configuration.
- config = Configuration(configFile, parserResults)
-
- # Generate the prototype list.
- generate_file(config, 'PrototypeList', 'PrototypeList.rs')
-
- # Generate the common code.
- generate_file(config, 'RegisterBindings', 'RegisterBindings.rs')
-
- # Generate the type list.
- generate_file(config, 'InterfaceTypes', 'InterfaceTypes.rs')
-
- # Generate the type list.
- generate_file(config, 'InheritTypes', 'InheritTypes.rs')
-
- # Generate the module declarations.
- generate_file(config, 'Bindings', 'Bindings/mod.rs')
-
- generate_file(config, 'UnionTypes', 'UnionTypes.rs')
-
-if __name__ == '__main__':
- main()
diff --git a/src/components/script/dom/bindings/codegen/Makefile.in b/src/components/script/dom/bindings/codegen/Makefile.in
deleted file mode 100644
index 5fef1e77218..00000000000
--- a/src/components/script/dom/bindings/codegen/Makefile.in
+++ /dev/null
@@ -1,165 +0,0 @@
-# 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/.
-
-DEPTH = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-FAIL_ON_WARNINGS := 1
-
-MODULE = dom
-LIBRARY_NAME = dombindings_s
-LIBXUL_LIBRARY = 1
-FORCE_STATIC_LIB = 1
-EXPORT_LIBRARY = 1
-
-include $(topsrcdir)/config/config.mk
-
-# Need this to find all our DOM source files.
-include $(topsrcdir)/dom/dom-config.mk
-
-include $(topsrcdir)/dom/webidl/WebIDL.mk
-
-binding_include_path := mozilla/dom
-all_webidl_files = $(webidl_files) $(generated_webidl_files)
-# Set exported_binding_headers before adding the test IDL to the mix
-exported_binding_headers := $(subst .webidl,Binding.h,$(all_webidl_files))
-# Set linked_binding_cpp_files before adding the test IDL to the mix
-linked_binding_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files))
-
-all_webidl_files += $(test_webidl_files)
-
-binding_header_files := $(subst .webidl,Binding.h,$(all_webidl_files))
-binding_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files))
-
-globalgen_targets := \
- PrototypeList.h \
- RegisterBindings.h \
- RegisterBindings.cpp \
- UnionTypes.h \
- UnionConversions.h \
- $(NULL)
-
-CPPSRCS = \
- $(linked_binding_cpp_files) \
- $(filter %.cpp, $(globalgen_targets)) \
- BindingUtils.cpp \
- DOMJSProxyHandler.cpp \
- $(NULL)
-
-EXPORTS_NAMESPACES = $(binding_include_path) mozilla
-
-EXPORTS_mozilla = \
- ErrorResult.h \
- $(NULL)
-
-EXPORTS_$(binding_include_path) = \
- BindingUtils.h \
- DOMJSClass.h \
- DOMJSProxyHandler.h \
- Errors.msg \
- Nullable.h \
- PrimitiveConversions.h \
- PrototypeList.h \
- RegisterBindings.h \
- TypedArray.h \
- UnionConversions.h \
- UnionTypes.h \
- $(exported_binding_headers) \
- $(NULL)
-
-LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
- -I$(topsrcdir)/js/xpconnect/wrappers \
- -I$(topsrcdir)/content/canvas/src \
- -I$(topsrcdir)/content/html/content/src
-
-include $(topsrcdir)/config/rules.mk
-
-# If you change bindinggen_dependencies here, change it in
-# dom/bindings/test/Makefile.in too.
-bindinggen_dependencies := \
- BindingGen.py \
- Bindings.conf \
- Configuration.py \
- Codegen.py \
- parser/WebIDL.py \
- ParserResults.pkl \
- $(GLOBAL_DEPS) \
- $(NULL)
-
-CSS2Properties.webidl: $(topsrcdir)/layout/style/nsCSSPropList.h \
- $(topsrcdir)/layout/style/nsCSSPropAliasList.h \
- $(webidl_base)/CSS2Properties.webidl.in \
- $(webidl_base)/CSS2PropertiesProps.h \
- $(srcdir)/GenerateCSS2PropertiesWebIDL.py \
- $(GLOBAL_DEPS)
- $(CPP) $(DEFINES) $(ACDEFINES) -I$(topsrcdir)/layout/style $(webidl_base)/CSS2PropertiesProps.h | \
- $(PYTHON) \
- $(srcdir)/GenerateCSS2PropertiesWebIDL.py $(webidl_base)/CSS2Properties.webidl.in > CSS2Properties.webidl
-
-$(webidl_files): %: $(webidl_base)/%
- $(INSTALL) $(IFLAGS1) $(webidl_base)/$* .
-
-$(test_webidl_files): %: $(srcdir)/test/%
- $(INSTALL) $(IFLAGS1) $(srcdir)/test/$* .
-
-$(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
- %.webidl \
- $(NULL)
- $(PYTHON) $(topsrcdir)/config/pythonpath.py \
- $(PLY_INCLUDE) -I$(srcdir)/parser \
- $(srcdir)/BindingGen.py header \
- $(srcdir)/Bindings.conf $*Binding \
- $*.webidl
-
-$(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
- %.webidl \
- $(NULL)
- $(PYTHON) $(topsrcdir)/config/pythonpath.py \
- $(PLY_INCLUDE) -I$(srcdir)/parser \
- $(srcdir)/BindingGen.py cpp \
- $(srcdir)/Bindings.conf $*Binding \
- $*.webidl
-
-$(globalgen_targets): ParserResults.pkl
-
-CACHE_DIR = _cache
-
-globalgen_dependencies := \
- GlobalGen.py \
- Bindings.conf \
- Configuration.py \
- Codegen.py \
- parser/WebIDL.py \
- $(CACHE_DIR)/.done \
- $(GLOBAL_DEPS) \
- $(NULL)
-
-$(CACHE_DIR)/.done:
- $(MKDIR) -p $(CACHE_DIR)
- @$(TOUCH) $@
-
-ParserResults.pkl: $(globalgen_dependencies) \
- $(all_webidl_files)
- $(PYTHON) $(topsrcdir)/config/pythonpath.py \
- $(PLY_INCLUDE) -I$(srcdir)/parser \
- $(srcdir)/GlobalGen.py $(srcdir)/Bindings.conf . \
- --cachedir=$(CACHE_DIR) \
- $(all_webidl_files)
-
-GARBAGE += \
- $(binding_header_files) \
- $(binding_cpp_files) \
- $(all_webidl_files) \
- $(globalgen_targets) \
- ParserResults.pkl \
- webidlyacc.py \
- parser.out \
- $(NULL)
-
-# Make sure all binding header files are created during the export stage, so we
-# don't have issues with .cpp files being compiled before we've generated the
-# headers they depend on. This is really only needed for the test files, since
-# the non-test headers are all exported above anyway.
-export:: $(binding_header_files)
diff --git a/src/components/script/dom/bindings/codegen/Nullable.h b/src/components/script/dom/bindings/codegen/Nullable.h
deleted file mode 100644
index 8b2cc08642b..00000000000
--- a/src/components/script/dom/bindings/codegen/Nullable.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
-/* 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/. */
-
-#ifndef mozilla_dom_Nullable_h
-#define mozilla_dom_Nullable_h
-
-#include "mozilla/Assertions.h"
-
-namespace mozilla {
-namespace dom {
-
-// Support for nullable types
-template <typename T>
-struct Nullable
-{
-private:
- T mValue;
- bool mIsNull;
-
-public:
- Nullable()
- : mIsNull(true)
- {}
-
- Nullable(T aValue)
- : mValue(aValue)
- , mIsNull(false)
- {}
-
- void SetValue(T aValue) {
- mValue = aValue;
- mIsNull = false;
- }
-
- // For cases when |T| is some type with nontrivial copy behavior, we may want
- // to get a reference to our internal copy of T and work with it directly
- // instead of relying on the copying version of SetValue().
- T& SetValue() {
- mIsNull = false;
- return mValue;
- }
-
- void SetNull() {
- mIsNull = true;
- }
-
- const T& Value() const {
- MOZ_ASSERT(!mIsNull);
- return mValue;
- }
-
- T& Value() {
- MOZ_ASSERT(!mIsNull);
- return mValue;
- }
-
- bool IsNull() const {
- return mIsNull;
- }
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif /* mozilla_dom_Nullable_h */
diff --git a/src/components/script/dom/bindings/codegen/PrimitiveConversions.h b/src/components/script/dom/bindings/codegen/PrimitiveConversions.h
deleted file mode 100644
index 40c27425772..00000000000
--- a/src/components/script/dom/bindings/codegen/PrimitiveConversions.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
-/* 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/. */
-
-/**
- * Conversions from jsval to primitive values
- */
-
-#ifndef mozilla_dom_PrimitiveConversions_h
-#define mozilla_dom_PrimitiveConversions_h
-
-#include <limits>
-#include <math.h>
-#include "mozilla/Assertions.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/FloatingPoint.h"
-#include "xpcpublic.h"
-
-namespace mozilla {
-namespace dom {
-
-template<typename T>
-struct TypeName {
-};
-
-template<>
-struct TypeName<int8_t> {
- static const char* value() {
- return "byte";
- }
-};
-template<>
-struct TypeName<uint8_t> {
- static const char* value() {
- return "octet";
- }
-};
-template<>
-struct TypeName<int16_t> {
- static const char* value() {
- return "short";
- }
-};
-template<>
-struct TypeName<uint16_t> {
- static const char* value() {
- return "unsigned short";
- }
-};
-template<>
-struct TypeName<int32_t> {
- static const char* value() {
- return "long";
- }
-};
-template<>
-struct TypeName<uint32_t> {
- static const char* value() {
- return "unsigned long";
- }
-};
-template<>
-struct TypeName<int64_t> {
- static const char* value() {
- return "long long";
- }
-};
-template<>
-struct TypeName<uint64_t> {
- static const char* value() {
- return "unsigned long long";
- }
-};
-
-
-enum ConversionBehavior {
- eDefault,
- eEnforceRange,
- eClamp
-};
-
-template<typename T, ConversionBehavior B>
-struct PrimitiveConversionTraits {
-};
-
-template<typename T>
-struct DisallowedConversion {
- typedef int jstype;
- typedef int intermediateType;
-
-private:
- static inline bool converter(JSContext* cx, JS::Value v, jstype* retval) {
- MOZ_NOT_REACHED("This should never be instantiated!");
- return false;
- }
-};
-
-struct PrimitiveConversionTraits_smallInt {
- // The output of JS::ToInt32 is determined as follows:
- // 1) The value is converted to a double
- // 2) Anything that's not a finite double returns 0
- // 3) The double is rounded towards zero to the nearest integer
- // 4) The resulting integer is reduced mod 2^32. The output of this
- // operation is an integer in the range [0, 2^32).
- // 5) If the resulting number is >= 2^31, 2^32 is subtracted from it.
- //
- // The result of all this is a number in the range [-2^31, 2^31)
- //
- // WebIDL conversions for the 8-bit, 16-bit, and 32-bit integer types
- // are defined in the same way, except that step 4 uses reduction mod
- // 2^8 and 2^16 for the 8-bit and 16-bit types respectively, and step 5
- // is only done for the signed types.
- //
- // C/C++ define integer conversion semantics to unsigned types as taking
- // your input integer mod (1 + largest value representable in the
- // unsigned type). Since 2^32 is zero mod 2^8, 2^16, and 2^32,
- // converting to the unsigned int of the relevant width will correctly
- // perform step 4; in particular, the 2^32 possibly subtracted in step 5
- // will become 0.
- //
- // Once we have step 4 done, we're just going to assume 2s-complement
- // representation and cast directly to the type we really want.
- //
- // So we can cast directly for all unsigned types and for int32_t; for
- // the smaller-width signed types we need to cast through the
- // corresponding unsigned type.
- typedef int32_t jstype;
- typedef int32_t intermediateType;
- static inline bool converter(JSContext* cx, JS::Value v, jstype* retval) {
- return JS::ToInt32(cx, v, retval);
- }
-};
-template<>
-struct PrimitiveConversionTraits<int8_t, eDefault> : PrimitiveConversionTraits_smallInt {
- typedef uint8_t intermediateType;
-};
-template<>
-struct PrimitiveConversionTraits<uint8_t, eDefault> : PrimitiveConversionTraits_smallInt {
-};
-template<>
-struct PrimitiveConversionTraits<int16_t, eDefault> : PrimitiveConversionTraits_smallInt {
- typedef uint16_t intermediateType;
-};
-template<>
-struct PrimitiveConversionTraits<uint16_t, eDefault> : PrimitiveConversionTraits_smallInt {
-};
-template<>
-struct PrimitiveConversionTraits<int32_t, eDefault> : PrimitiveConversionTraits_smallInt {
-};
-template<>
-struct PrimitiveConversionTraits<uint32_t, eDefault> : PrimitiveConversionTraits_smallInt {
-};
-
-template<>
-struct PrimitiveConversionTraits<int64_t, eDefault> {
- typedef int64_t jstype;
- typedef int64_t intermediateType;
- static inline bool converter(JSContext* cx, JS::Value v, jstype* retval) {
- return JS::ToInt64(cx, v, retval);
- }
-};
-
-template<>
-struct PrimitiveConversionTraits<uint64_t, eDefault> {
- typedef uint64_t jstype;
- typedef uint64_t intermediateType;
- static inline bool converter(JSContext* cx, JS::Value v, jstype* retval) {
- return JS::ToUint64(cx, v, retval);
- }
-};
-
-template<typename T>
-struct PrimitiveConversionTraits_Limits {
- static inline T min() {
- return std::numeric_limits<T>::min();
- }
- static inline T max() {
- return std::numeric_limits<T>::max();
- }
-};
-
-template<>
-struct PrimitiveConversionTraits_Limits<int64_t> {
- static inline int64_t min() {
- return -(1LL << 53) + 1;
- }
- static inline int64_t max() {
- return (1LL << 53) - 1;
- }
-};
-
-template<>
-struct PrimitiveConversionTraits_Limits<uint64_t> {
- static inline uint64_t min() {
- return 0;
- }
- static inline uint64_t max() {
- return (1LL << 53) - 1;
- }
-};
-
-template<typename T, bool (*Enforce)(JSContext* cx, const double& d, T* retval)>
-struct PrimitiveConversionTraits_ToCheckedIntHelper {
- typedef T jstype;
- typedef T intermediateType;
-
- static inline bool converter(JSContext* cx, JS::Value v, jstype* retval) {
- double intermediate;
- if (!JS::ToNumber(cx, v, &intermediate)) {
- return false;
- }
-
- return Enforce(cx, intermediate, retval);
- }
-};
-
-template<typename T>
-inline bool
-PrimitiveConversionTraits_EnforceRange(JSContext* cx, const double& d, T* retval)
-{
- MOZ_STATIC_ASSERT(std::numeric_limits<T>::is_integer,
- "This can only be applied to integers!");
-
- if (!MOZ_DOUBLE_IS_FINITE(d)) {
- return ThrowErrorMessage(cx, MSG_ENFORCE_RANGE_NON_FINITE, TypeName<T>::value());
- }
-
- bool neg = (d < 0);
- double rounded = floor(neg ? -d : d);
- rounded = neg ? -rounded : rounded;
- if (rounded < PrimitiveConversionTraits_Limits<T>::min() ||
- rounded > PrimitiveConversionTraits_Limits<T>::max()) {
- return ThrowErrorMessage(cx, MSG_ENFORCE_RANGE_OUT_OF_RANGE, TypeName<T>::value());
- }
-
- *retval = static_cast<T>(rounded);
- return true;
-}
-
-template<typename T>
-struct PrimitiveConversionTraits<T, eEnforceRange> :
- public PrimitiveConversionTraits_ToCheckedIntHelper<T, PrimitiveConversionTraits_EnforceRange<T> > {
-};
-
-template<typename T>
-inline bool
-PrimitiveConversionTraits_Clamp(JSContext* cx, const double& d, T* retval)
-{
- MOZ_STATIC_ASSERT(std::numeric_limits<T>::is_integer,
- "This can only be applied to integers!");
-
- if (MOZ_DOUBLE_IS_NaN(d)) {
- *retval = 0;
- return true;
- }
- if (d >= PrimitiveConversionTraits_Limits<T>::max()) {
- *retval = PrimitiveConversionTraits_Limits<T>::max();
- return true;
- }
- if (d <= PrimitiveConversionTraits_Limits<T>::min()) {
- *retval = PrimitiveConversionTraits_Limits<T>::min();
- return true;
- }
-
- MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(d));
-
- // Banker's rounding (round ties towards even).
- // We move away from 0 by 0.5f and then truncate. That gets us the right
- // answer for any starting value except plus or minus N.5. With a starting
- // value of that form, we now have plus or minus N+1. If N is odd, this is
- // the correct result. If N is even, plus or minus N is the correct result.
- double toTruncate = (d < 0) ? d - 0.5 : d + 0.5;
-
- T truncated(toTruncate);
-
- if (truncated == toTruncate) {
- /*
- * It was a tie (since moving away from 0 by 0.5 gave us the exact integer
- * we want). Since we rounded away from 0, we either already have an even
- * number or we have an odd number but the number we want is one closer to
- * 0. So just unconditionally masking out the ones bit should do the trick
- * to get us the value we want.
- */
- truncated &= ~1;
- }
-
- *retval = truncated;
- return true;
-}
-
-template<typename T>
-struct PrimitiveConversionTraits<T, eClamp> :
- public PrimitiveConversionTraits_ToCheckedIntHelper<T, PrimitiveConversionTraits_Clamp<T> > {
-};
-
-
-template<ConversionBehavior B>
-struct PrimitiveConversionTraits<bool, B> : public DisallowedConversion<bool> {};
-
-template<>
-struct PrimitiveConversionTraits<bool, eDefault> {
- typedef JSBool jstype;
- typedef bool intermediateType;
- static inline bool converter(JSContext* /* unused */, JS::Value v, jstype* retval) {
- *retval = JS::ToBoolean(v);
- return true;
- }
-};
-
-
-template<ConversionBehavior B>
-struct PrimitiveConversionTraits<float, B> : public DisallowedConversion<float> {};
-
-template<ConversionBehavior B>
-struct PrimitiveConversionTraits<double, B> : public DisallowedConversion<double> {};
-
-struct PrimitiveConversionTraits_float {
- typedef double jstype;
- typedef double intermediateType;
- static inline bool converter(JSContext* cx, JS::Value v, jstype* retval) {
- return JS::ToNumber(cx, v, retval);
- }
-};
-
-template<>
-struct PrimitiveConversionTraits<float, eDefault> : PrimitiveConversionTraits_float {
-};
-template<>
-struct PrimitiveConversionTraits<double, eDefault> : PrimitiveConversionTraits_float {
-};
-
-
-template<typename T, ConversionBehavior B>
-bool ValueToPrimitive(JSContext* cx, JS::Value v, T* retval)
-{
- typename PrimitiveConversionTraits<T, B>::jstype t;
- if (!PrimitiveConversionTraits<T, B>::converter(cx, v, &t))
- return false;
-
- *retval =
- static_cast<typename PrimitiveConversionTraits<T, B>::intermediateType>(t);
- return true;
-}
-
-} // namespace dom
-} // namespace mozilla
-
-#endif /* mozilla_dom_PrimitiveConversions_h */
diff --git a/src/components/script/dom/bindings/codegen/RegisterBindings.h b/src/components/script/dom/bindings/codegen/RegisterBindings.h
deleted file mode 100644
index 7d83a747cc3..00000000000
--- a/src/components/script/dom/bindings/codegen/RegisterBindings.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef mozilla_dom_RegisterBindings_h__
-#define mozilla_dom_RegisterBindings_h__
-
-
-namespace mozilla {
-namespace dom {
-void
-Register(nsScriptNameSpaceManager* aNameSpaceManager);
-
-} // namespace dom
-} // namespace mozilla
-
-
-#endif // mozilla_dom_RegisterBindings_h__
diff --git a/src/components/script/dom/bindings/codegen/TypedArray.h b/src/components/script/dom/bindings/codegen/TypedArray.h
deleted file mode 100644
index 2a6f17bcb96..00000000000
--- a/src/components/script/dom/bindings/codegen/TypedArray.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
-/* 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/. */
-
-#ifndef mozilla_dom_TypedArray_h
-#define mozilla_dom_TypedArray_h
-
-#include "jsfriendapi.h"
-
-namespace mozilla {
-namespace dom {
-
-/*
- * Various typed array classes for argument conversion. We have a base class
- * that has a way of initializing a TypedArray from an existing typed array, and
- * a subclass of the base class that supports creation of a relevant typed array
- * or array buffer object.
- */
-template<typename T,
- JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**)>
-struct TypedArray_base {
- TypedArray_base(JSContext* cx, JSObject* obj)
- {
- mObj = UnboxArray(cx, obj, &mLength, &mData);
- }
-
-private:
- T* mData;
- uint32_t mLength;
- JSObject* mObj;
-
-public:
- inline bool inited() const {
- return !!mObj;
- }
-
- inline T *Data() const {
- MOZ_ASSERT(inited());
- return mData;
- }
-
- inline uint32_t Length() const {
- MOZ_ASSERT(inited());
- return mLength;
- }
-
- inline JSObject *Obj() const {
- MOZ_ASSERT(inited());
- return mObj;
- }
-};
-
-
-template<typename T,
- T* GetData(JSObject*, JSContext*),
- JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**),
- JSObject* CreateNew(JSContext*, uint32_t)>
-struct TypedArray : public TypedArray_base<T,UnboxArray> {
- TypedArray(JSContext* cx, JSObject* obj) :
- TypedArray_base<T,UnboxArray>(cx, obj)
- {}
-
- static inline JSObject*
- Create(JSContext* cx, nsWrapperCache* creator, uint32_t length,
- const T* data = NULL) {
- JSObject* creatorWrapper;
- Maybe<JSAutoCompartment> ac;
- if (creator && (creatorWrapper = creator->GetWrapperPreserveColor())) {
- ac.construct(cx, creatorWrapper);
- }
- JSObject* obj = CreateNew(cx, length);
- if (!obj) {
- return NULL;
- }
- if (data) {
- T* buf = static_cast<T*>(GetData(obj, cx));
- memcpy(buf, data, length*sizeof(T));
- }
- return obj;
- }
-};
-
-typedef TypedArray<int8_t, JS_GetInt8ArrayData, JS_GetObjectAsInt8Array,
- JS_NewInt8Array>
- Int8Array;
-typedef TypedArray<uint8_t, JS_GetUint8ArrayData,
- JS_GetObjectAsUint8Array, JS_NewUint8Array>
- Uint8Array;
-typedef TypedArray<uint8_t, JS_GetUint8ClampedArrayData,
- JS_GetObjectAsUint8ClampedArray, JS_NewUint8ClampedArray>
- Uint8ClampedArray;
-typedef TypedArray<int16_t, JS_GetInt16ArrayData,
- JS_GetObjectAsInt16Array, JS_NewInt16Array>
- Int16Array;
-typedef TypedArray<uint16_t, JS_GetUint16ArrayData,
- JS_GetObjectAsUint16Array, JS_NewUint16Array>
- Uint16Array;
-typedef TypedArray<int32_t, JS_GetInt32ArrayData,
- JS_GetObjectAsInt32Array, JS_NewInt32Array>
- Int32Array;
-typedef TypedArray<uint32_t, JS_GetUint32ArrayData,
- JS_GetObjectAsUint32Array, JS_NewUint32Array>
- Uint32Array;
-typedef TypedArray<float, JS_GetFloat32ArrayData,
- JS_GetObjectAsFloat32Array, JS_NewFloat32Array>
- Float32Array;
-typedef TypedArray<double, JS_GetFloat64ArrayData,
- JS_GetObjectAsFloat64Array, JS_NewFloat64Array>
- Float64Array;
-typedef TypedArray_base<uint8_t, JS_GetObjectAsArrayBufferView>
- ArrayBufferView;
-typedef TypedArray<uint8_t, JS_GetArrayBufferData,
- JS_GetObjectAsArrayBuffer, JS_NewArrayBuffer>
- ArrayBuffer;
-
-} // namespace dom
-} // namespace mozilla
-
-#endif /* mozilla_dom_TypedArray_h */
diff --git a/src/components/script/dom/bindings/codegen/crashtests/769464.html b/src/components/script/dom/bindings/codegen/crashtests/769464.html
deleted file mode 100644
index 84d6dbc08b4..00000000000
--- a/src/components/script/dom/bindings/codegen/crashtests/769464.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<script>
-
-function boom()
-{
- window.getComputedStyle(new Worker("404.js"));
-}
-
-window.addEventListener("load", boom, false);
-
-</script>
diff --git a/src/components/script/dom/bindings/codegen/crashtests/crashtests.list b/src/components/script/dom/bindings/codegen/crashtests/crashtests.list
deleted file mode 100644
index cb954bd91fc..00000000000
--- a/src/components/script/dom/bindings/codegen/crashtests/crashtests.list
+++ /dev/null
@@ -1 +0,0 @@
-asserts-if(cocoaWidget,0-1) load 769464.html
diff --git a/src/components/script/dom/bindings/codegen/parser/README b/src/components/script/dom/bindings/codegen/parser/README
deleted file mode 100644
index 94b64b88459..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/README
+++ /dev/null
@@ -1 +0,0 @@
-A WebIDL parser written in Python to be used in Mozilla. \ No newline at end of file
diff --git a/src/components/script/dom/bindings/codegen/parser/UPSTREAM b/src/components/script/dom/bindings/codegen/parser/UPSTREAM
deleted file mode 100644
index 7ac5899379e..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/UPSTREAM
+++ /dev/null
@@ -1 +0,0 @@
-http://dev.w3.org/cvsweb/~checkout~/2006/webapi/WebIDL/Overview.html?rev=1.409;content-type=text%2Fhtml%3b+charset=utf-8 \ No newline at end of file
diff --git a/src/components/script/dom/bindings/codegen/parser/WebIDL.py b/src/components/script/dom/bindings/codegen/parser/WebIDL.py
deleted file mode 100644
index 32f80e82c56..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ /dev/null
@@ -1,5583 +0,0 @@
-# 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/.
-
-""" A WebIDL parser. """
-
-from ply import lex, yacc
-import re
-import os
-import traceback
-import math
-from collections import defaultdict
-
-# Machinery
-
-def parseInt(literal):
- string = literal
- sign = 0
- base = 0
-
- if string[0] == '-':
- sign = -1
- string = string[1:]
- else:
- sign = 1
-
- if string[0] == '0' and len(string) > 1:
- if string[1] == 'x' or string[1] == 'X':
- base = 16
- string = string[2:]
- else:
- base = 8
- string = string[1:]
- else:
- base = 10
-
- value = int(string, base)
- return value * sign
-
-# Magic for creating enums
-def M_add_class_attribs(attribs, start):
- def foo(name, bases, dict_):
- for v, k in enumerate(attribs):
- dict_[k] = start + v
- assert 'length' not in dict_
- dict_['length'] = start + len(attribs)
- return type(name, bases, dict_)
- return foo
-
-def enum(*names, **kw):
- if len(kw) == 1:
- base = kw['base'].__class__
- start = base.length
- else:
- assert len(kw) == 0
- base = object
- start = 0
- class Foo(base):
- __metaclass__ = M_add_class_attribs(names, start)
- def __setattr__(self, name, value): # this makes it read-only
- raise NotImplementedError
- return Foo()
-
-class WebIDLError(Exception):
- def __init__(self, message, locations, warning=False):
- self.message = message
- self.locations = [str(loc) for loc in locations]
- self.warning = warning
-
- def __str__(self):
- return "%s: %s%s%s" % (self.warning and 'warning' or 'error',
- self.message,
- ", " if len(self.locations) != 0 else "",
- "\n".join(self.locations))
-
-class Location(object):
- def __init__(self, lexer, lineno, lexpos, filename):
- self._line = None
- self._lineno = lineno
- self._lexpos = lexpos
- self._lexdata = lexer.lexdata
- self._file = filename if filename else "<unknown>"
-
- def __eq__(self, other):
- return self._lexpos == other._lexpos and \
- self._file == other._file
-
- def filename(self):
- return self._file
-
- def resolve(self):
- if self._line:
- return
-
- startofline = self._lexdata.rfind('\n', 0, self._lexpos) + 1
- endofline = self._lexdata.find('\n', self._lexpos, self._lexpos + 80)
- if endofline != -1:
- self._line = self._lexdata[startofline:endofline]
- else:
- self._line = self._lexdata[startofline:]
- self._colno = self._lexpos - startofline
-
- # Our line number seems to point to the start of self._lexdata
- self._lineno += self._lexdata.count('\n', 0, startofline)
-
- def get(self):
- self.resolve()
- return "%s line %s:%s" % (self._file, self._lineno, self._colno)
-
- def _pointerline(self):
- return " " * self._colno + "^"
-
- def __str__(self):
- self.resolve()
- return "%s line %s:%s\n%s\n%s" % (self._file, self._lineno, self._colno,
- self._line, self._pointerline())
-
-class BuiltinLocation(object):
- def __init__(self, text):
- self.msg = text + "\n"
-
- def __eq__(self, other):
- return isinstance(other, BuiltinLocation) and \
- self.msg == other.msg
-
- def filename(self):
- return '<builtin>'
-
- def resolve(self):
- pass
-
- def get(self):
- return self.msg
-
- def __str__(self):
- return self.get()
-
-
-# Data Model
-
-class IDLObject(object):
- def __init__(self, location):
- self.location = location
- self.userData = dict()
-
- def filename(self):
- return self.location.filename()
-
- def isInterface(self):
- return False
-
- def isEnum(self):
- return False
-
- def isCallback(self):
- return False
-
- def isType(self):
- return False
-
- def isDictionary(self):
- return False;
-
- def isUnion(self):
- return False
-
- def getUserData(self, key, default):
- return self.userData.get(key, default)
-
- def setUserData(self, key, value):
- self.userData[key] = value
-
- def addExtendedAttributes(self, attrs):
- assert False # Override me!
-
- def handleExtendedAttribute(self, attr):
- assert False # Override me!
-
- def _getDependentObjects(self):
- assert False # Override me!
-
- def getDeps(self, visited=None):
- """ Return a set of files that this object depends on. If any of
- these files are changed the parser needs to be rerun to regenerate
- a new IDLObject.
-
- The visited argument is a set of all the objects already visited.
- We must test to see if we are in it, and if so, do nothing. This
- prevents infinite recursion."""
-
- # NB: We can't use visited=set() above because the default value is
- # evaluated when the def statement is evaluated, not when the function
- # is executed, so there would be one set for all invocations.
- if visited == None:
- visited = set()
-
- if self in visited:
- return set()
-
- visited.add(self)
-
- deps = set()
- if self.filename() != "<builtin>":
- deps.add(self.filename())
-
- for d in self._getDependentObjects():
- deps = deps.union(d.getDeps(visited))
-
- return deps
-
-class IDLScope(IDLObject):
- def __init__(self, location, parentScope, identifier):
- IDLObject.__init__(self, location)
-
- self.parentScope = parentScope
- if identifier:
- assert isinstance(identifier, IDLIdentifier)
- self._name = identifier
- else:
- self._name = None
-
- self._dict = {}
- self.globalNames = set()
- # A mapping from global name to the set of global interfaces
- # that have that global name.
- self.globalNameMapping = defaultdict(set)
- self.primaryGlobalAttr = None
- self.primaryGlobalName = None
-
- def __str__(self):
- return self.QName()
-
- def QName(self):
- if self._name:
- return self._name.QName() + "::"
- return "::"
-
- def ensureUnique(self, identifier, object):
- """
- Ensure that there is at most one 'identifier' in scope ('self').
- Note that object can be None. This occurs if we end up here for an
- interface type we haven't seen yet.
- """
- assert isinstance(identifier, IDLUnresolvedIdentifier)
- assert not object or isinstance(object, IDLObjectWithIdentifier)
- assert not object or object.identifier == identifier
-
- if identifier.name in self._dict:
- if not object:
- return
-
- # ensureUnique twice with the same object is not allowed
- assert id(object) != id(self._dict[identifier.name])
-
- replacement = self.resolveIdentifierConflict(self, identifier,
- self._dict[identifier.name],
- object)
- self._dict[identifier.name] = replacement
- return
-
- assert object
-
- self._dict[identifier.name] = object
-
- def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
- if isinstance(originalObject, IDLExternalInterface) and \
- isinstance(newObject, IDLExternalInterface) and \
- originalObject.identifier.name == newObject.identifier.name:
- return originalObject
-
- if (isinstance(originalObject, IDLExternalInterface) or
- isinstance(newObject, IDLExternalInterface)):
- raise WebIDLError(
- "Name collision between "
- "interface declarations for identifier '%s' at '%s' and '%s'"
- % (identifier.name,
- originalObject.location, newObject.location), [])
-
- if (isinstance(originalObject, IDLDictionary) or
- isinstance(newObject, IDLDictionary)):
- raise WebIDLError(
- "Name collision between dictionary declarations for "
- "identifier '%s'.\n%s\n%s"
- % (identifier.name,
- originalObject.location, newObject.location), [])
-
- # We do the merging of overloads here as opposed to in IDLInterface
- # because we need to merge overloads of NamedConstructors and we need to
- # detect conflicts in those across interfaces. See also the comment in
- # IDLInterface.addExtendedAttributes for "NamedConstructor".
- if originalObject.tag == IDLInterfaceMember.Tags.Method and \
- newObject.tag == IDLInterfaceMember.Tags.Method:
- return originalObject.addOverload(newObject)
-
- # Default to throwing, derived classes can override.
- conflictdesc = "\n\t%s at %s\n\t%s at %s" % \
- (originalObject, originalObject.location, newObject, newObject.location)
-
- raise WebIDLError(
- "Multiple unresolvable definitions of identifier '%s' in scope '%s%s"
- % (identifier.name, str(self), conflictdesc), [])
-
- def _lookupIdentifier(self, identifier):
- return self._dict[identifier.name]
-
- def lookupIdentifier(self, identifier):
- assert isinstance(identifier, IDLIdentifier)
- assert identifier.scope == self
- return self._lookupIdentifier(identifier)
-
-class IDLIdentifier(IDLObject):
- def __init__(self, location, scope, name):
- IDLObject.__init__(self, location)
-
- self.name = name
- assert isinstance(scope, IDLScope)
- self.scope = scope
-
- def __str__(self):
- return self.QName()
-
- def QName(self):
- return self.scope.QName() + self.name
-
- def __hash__(self):
- return self.QName().__hash__()
-
- def __eq__(self, other):
- return self.QName() == other.QName()
-
- def object(self):
- return self.scope.lookupIdentifier(self)
-
-class IDLUnresolvedIdentifier(IDLObject):
- def __init__(self, location, name, allowDoubleUnderscore = False,
- allowForbidden = False):
- IDLObject.__init__(self, location)
-
- assert len(name) > 0
-
- if name[:2] == "__" and name != "__content" and name != "___noSuchMethod__" and not allowDoubleUnderscore:
- raise WebIDLError("Identifiers beginning with __ are reserved",
- [location])
- if name[0] == '_' and not allowDoubleUnderscore:
- name = name[1:]
- # TODO: Bug 872377, Restore "toJSON" to below list.
- # We sometimes need custom serialization, so allow toJSON for now.
- if (name in ["constructor", "toString"] and
- not allowForbidden):
- raise WebIDLError("Cannot use reserved identifier '%s'" % (name),
- [location])
-
- self.name = name
-
- def __str__(self):
- return self.QName()
-
- def QName(self):
- return "<unresolved scope>::" + self.name
-
- def resolve(self, scope, object):
- assert isinstance(scope, IDLScope)
- assert not object or isinstance(object, IDLObjectWithIdentifier)
- assert not object or object.identifier == self
-
- scope.ensureUnique(self, object)
-
- identifier = IDLIdentifier(self.location, scope, self.name)
- if object:
- object.identifier = identifier
- return identifier
-
- def finish(self):
- assert False # Should replace with a resolved identifier first.
-
-class IDLObjectWithIdentifier(IDLObject):
- def __init__(self, location, parentScope, identifier):
- IDLObject.__init__(self, location)
-
- assert isinstance(identifier, IDLUnresolvedIdentifier)
-
- self.identifier = identifier
-
- if parentScope:
- self.resolve(parentScope)
-
- self.treatNullAs = "Default"
-
- def resolve(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- assert isinstance(self.identifier, IDLUnresolvedIdentifier)
- self.identifier.resolve(parentScope, self)
-
- def checkForStringHandlingExtendedAttributes(self, attrs,
- isDictionaryMember=False,
- isOptional=False):
- """
- A helper function to deal with TreatNullAs. Returns the list
- of attrs it didn't handle itself.
- """
- assert isinstance(self, IDLArgument) or isinstance(self, IDLAttribute)
- unhandledAttrs = list()
- for attr in attrs:
- if not attr.hasValue():
- unhandledAttrs.append(attr)
- continue
-
- identifier = attr.identifier()
- value = attr.value()
- if identifier == "TreatNullAs":
- if not self.type.isDOMString() or self.type.nullable():
- raise WebIDLError("[TreatNullAs] is only allowed on "
- "arguments or attributes whose type is "
- "DOMString",
- [self.location])
- if isDictionaryMember:
- raise WebIDLError("[TreatNullAs] is not allowed for "
- "dictionary members", [self.location])
- if value != 'EmptyString':
- raise WebIDLError("[TreatNullAs] must take the identifier "
- "'EmptyString', not '%s'" % value,
- [self.location])
- self.treatNullAs = value
- else:
- unhandledAttrs.append(attr)
-
- return unhandledAttrs
-
-class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope):
- def __init__(self, location, parentScope, identifier):
- assert isinstance(identifier, IDLUnresolvedIdentifier)
-
- IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
- IDLScope.__init__(self, location, parentScope, self.identifier)
-
-class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
- def __init__(self, location, identifier):
- assert isinstance(identifier, IDLUnresolvedIdentifier)
- IDLObjectWithIdentifier.__init__(self, location, None, identifier)
-
- def finish(self, scope):
- try:
- scope._lookupIdentifier(self.identifier)
- except:
- raise WebIDLError("Unresolved type '%s'." % self.identifier,
- [self.location])
-
- obj = self.identifier.resolve(scope, None)
- return scope.lookupIdentifier(obj)
-
-class IDLExternalInterface(IDLObjectWithIdentifier):
- def __init__(self, location, parentScope, identifier):
- raise WebIDLError("Servo does not support external interfaces.",
- [self.location])
-
-class IDLPartialInterface(IDLObject):
- def __init__(self, location, name, members, nonPartialInterface):
- assert isinstance(name, IDLUnresolvedIdentifier)
-
- IDLObject.__init__(self, location)
- self.identifier = name
- self.members = members
- # propagatedExtendedAttrs are the ones that should get
- # propagated to our non-partial interface.
- self.propagatedExtendedAttrs = []
- self._nonPartialInterface = nonPartialInterface
- self._finished = False
- nonPartialInterface.addPartialInterface(self)
-
- def addExtendedAttributes(self, attrs):
- for attr in attrs:
- identifier = attr.identifier()
-
- if identifier in ["Constructor", "NamedConstructor"]:
- self.propagatedExtendedAttrs.append(attr)
- elif identifier == "Exposed":
- # This just gets propagated to all our members.
- for member in self.members:
- if len(member._exposureGlobalNames) != 0:
- raise WebIDLError("[Exposed] specified on both a "
- "partial interface member and on the "
- "partial interface itself",
- [member.location, attr.location])
- member.addExtendedAttributes([attr])
- else:
- raise WebIDLError("Unknown extended attribute %s on partial "
- "interface" % identifier,
- [attr.location])
-
- def finish(self, scope):
- if self._finished:
- return
- self._finished = True
- # Need to make sure our non-partial interface gets finished so it can
- # report cases when we only have partial interfaces.
- self._nonPartialInterface.finish(scope)
-
- def validate(self):
- pass
-
-
-def convertExposedAttrToGlobalNameSet(exposedAttr, targetSet):
- assert len(targetSet) == 0
- if exposedAttr.hasValue():
- targetSet.add(exposedAttr.value())
- else:
- assert exposedAttr.hasArgs()
- targetSet.update(exposedAttr.args())
-
-def globalNameSetToExposureSet(globalScope, nameSet, exposureSet):
- for name in nameSet:
- exposureSet.update(globalScope.globalNameMapping[name])
-
-class IDLInterface(IDLObjectWithScope):
- def __init__(self, location, parentScope, name, parent, members,
- isKnownNonPartial):
- assert isinstance(parentScope, IDLScope)
- assert isinstance(name, IDLUnresolvedIdentifier)
- assert isKnownNonPartial or not parent
- assert isKnownNonPartial or len(members) == 0
-
- self.parent = None
- self._callback = False
- self._finished = False
- self.members = []
- self._partialInterfaces = []
- self._extendedAttrDict = {}
- # namedConstructors needs deterministic ordering because bindings code
- # outputs the constructs in the order that namedConstructors enumerates
- # them.
- self.namedConstructors = list()
- self.implementedInterfaces = set()
- self._consequential = False
- self._isKnownNonPartial = False
- # self.interfacesBasedOnSelf is the set of interfaces that inherit from
- # self or have self as a consequential interface, including self itself.
- # Used for distinguishability checking.
- self.interfacesBasedOnSelf = set([self])
- # self.interfacesImplementingSelf is the set of interfaces that directly
- # have self as a consequential interface
- self.interfacesImplementingSelf = set()
- self._hasChildInterfaces = False
- self._isOnGlobalProtoChain = False
- # Tracking of the number of reserved slots we need for our
- # members and those of ancestor interfaces.
- self.totalMembersInSlots = 0
- # Tracking of the number of own own members we have in slots
- self._ownMembersInSlots = 0
- # _exposureGlobalNames are the global names listed in our [Exposed]
- # extended attribute. exposureSet is the exposure set as defined in the
- # Web IDL spec: it contains interface names.
- self._exposureGlobalNames = set()
- self.exposureSet = set()
-
- IDLObjectWithScope.__init__(self, location, parentScope, name)
-
- if isKnownNonPartial:
- self.setNonPartial(location, parent, members)
-
- def __str__(self):
- return "Interface '%s'" % self.identifier.name
-
- def ctor(self):
- identifier = IDLUnresolvedIdentifier(self.location, "constructor",
- allowForbidden=True)
- try:
- return self._lookupIdentifier(identifier)
- except:
- return None
-
- def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
- assert isinstance(scope, IDLScope)
- assert isinstance(originalObject, IDLInterfaceMember)
- assert isinstance(newObject, IDLInterfaceMember)
-
- retval = IDLScope.resolveIdentifierConflict(self, scope, identifier,
- originalObject, newObject)
-
- # Might be a ctor, which isn't in self.members
- if newObject in self.members:
- self.members.remove(newObject)
- return retval
-
- def finish(self, scope):
- if self._finished:
- return
-
- self._finished = True
-
- if not self._isKnownNonPartial:
- raise WebIDLError("Interface %s does not have a non-partial "
- "declaration" % self.identifier.name,
- [self.location])
-
- # Verify that our [Exposed] value, if any, makes sense.
- for globalName in self._exposureGlobalNames:
- if globalName not in scope.globalNames:
- raise WebIDLError("Unknown [Exposed] value %s" % globalName,
- [self.location])
-
- if len(self._exposureGlobalNames) == 0:
- self._exposureGlobalNames.add(scope.primaryGlobalName)
-
- globalNameSetToExposureSet(scope, self._exposureGlobalNames,
- self.exposureSet)
-
- # Now go ahead and merge in our partial interfaces.
- for partial in self._partialInterfaces:
- partial.finish(scope)
- self.addExtendedAttributes(partial.propagatedExtendedAttrs)
- self.members.extend(partial.members)
-
- # Now that we've merged in our partial interfaces, set the
- # _exposureGlobalNames on any members that don't have it set yet. Note
- # that any partial interfaces that had [Exposed] set have already set up
- # _exposureGlobalNames on all the members coming from them, so this is
- # just implementing the "members default to interface that defined them"
- # and "partial interfaces default to interface they're a partial for"
- # rules from the spec.
- for m in self.members:
- # If m, or the partial interface m came from, had [Exposed]
- # specified, it already has a nonempty exposure global names set.
- if len(m._exposureGlobalNames) == 0:
- m._exposureGlobalNames.update(self._exposureGlobalNames)
-
- assert not self.parent or isinstance(self.parent, IDLIdentifierPlaceholder)
- parent = self.parent.finish(scope) if self.parent else None
- if parent and isinstance(parent, IDLExternalInterface):
- raise WebIDLError("%s inherits from %s which does not have "
- "a definition" %
- (self.identifier.name,
- self.parent.identifier.name),
- [self.location])
- assert not parent or isinstance(parent, IDLInterface)
-
- self.parent = parent
-
- assert iter(self.members)
-
- if self.parent:
- self.parent.finish(scope)
-
- self.parent._hasChildInterfaces = True
-
- self.totalMembersInSlots = self.parent.totalMembersInSlots
-
- # Interfaces with [Global] or [PrimaryGlobal] must not
- # have anything inherit from them
- if (self.parent.getExtendedAttribute("Global") or
- self.parent.getExtendedAttribute("PrimaryGlobal")):
- # Note: This is not a self.parent.isOnGlobalProtoChain() check
- # because ancestors of a [Global] interface can have other
- # descendants.
- raise WebIDLError("[Global] interface has another interface "
- "inheriting from it",
- [self.location, self.parent.location])
-
- # Make sure that we're not exposed in places where our parent is not
- if not self.exposureSet.issubset(self.parent.exposureSet):
- raise WebIDLError("Interface %s is exposed in globals where its "
- "parent interface %s is not exposed." %
- (self.identifier.name,
- self.parent.identifier.name),
- [self.location, self.parent.location])
-
- # Callbacks must not inherit from non-callbacks or inherit from
- # anything that has consequential interfaces.
- # XXXbz Can non-callbacks inherit from callbacks? Spec issue pending.
- # XXXbz Can callbacks have consequential interfaces? Spec issue pending
- if self.isCallback():
- if not self.parent.isCallback():
- raise WebIDLError("Callback interface %s inheriting from "
- "non-callback interface %s" %
- (self.identifier.name,
- self.parent.identifier.name),
- [self.location, self.parent.location])
- elif self.parent.isCallback():
- raise WebIDLError("Non-callback interface %s inheriting from "
- "callback interface %s" %
- (self.identifier.name,
- self.parent.identifier.name),
- [self.location, self.parent.location])
-
- for iface in self.implementedInterfaces:
- iface.finish(scope)
-
- cycleInGraph = self.findInterfaceLoopPoint(self)
- if cycleInGraph:
- raise WebIDLError("Interface %s has itself as ancestor or "
- "implemented interface" % self.identifier.name,
- [self.location, cycleInGraph.location])
-
- if self.isCallback():
- # "implements" should have made sure we have no
- # consequential interfaces.
- assert len(self.getConsequentialInterfaces()) == 0
- # And that we're not consequential.
- assert not self.isConsequential()
-
- # Now resolve() and finish() our members before importing the
- # ones from our implemented interfaces.
-
- # resolve() will modify self.members, so we need to iterate
- # over a copy of the member list here.
- for member in list(self.members):
- member.resolve(self)
-
- for member in self.members:
- member.finish(scope)
-
- # Now that we've finished our members, which has updated their exposure
- # sets, make sure they aren't exposed in places where we are not.
- for member in self.members:
- if not member.exposureSet.issubset(self.exposureSet):
- raise WebIDLError("Interface member has larger exposure set "
- "than the interface itself",
- [member.location, self.location])
-
- ctor = self.ctor()
- if ctor is not None:
- ctor.finish(scope)
-
- for ctor in self.namedConstructors:
- ctor.finish(scope)
-
- # Make a copy of our member list, so things that implement us
- # can get those without all the stuff we implement ourselves
- # admixed.
- self.originalMembers = list(self.members)
-
- # Import everything from our consequential interfaces into
- # self.members. Sort our consequential interfaces by name
- # just so we have a consistent order.
- for iface in sorted(self.getConsequentialInterfaces(),
- cmp=cmp,
- key=lambda x: x.identifier.name):
- # Flag the interface as being someone's consequential interface
- iface.setIsConsequentialInterfaceOf(self)
- # Verify that we're not exposed somewhere where iface is not exposed
- if not self.exposureSet.issubset(iface.exposureSet):
- raise WebIDLError("Interface %s is exposed in globals where its "
- "consequential interface %s is not exposed." %
- (self.identifier.name, iface.identifier.name),
- [self.location, iface.location])
- additionalMembers = iface.originalMembers;
- for additionalMember in additionalMembers:
- for member in self.members:
- if additionalMember.identifier.name == member.identifier.name:
- raise WebIDLError(
- "Multiple definitions of %s on %s coming from 'implements' statements" %
- (member.identifier.name, self),
- [additionalMember.location, member.location])
- self.members.extend(additionalMembers)
- iface.interfacesImplementingSelf.add(self)
-
- for ancestor in self.getInheritedInterfaces():
- ancestor.interfacesBasedOnSelf.add(self)
- for ancestorConsequential in ancestor.getConsequentialInterfaces():
- ancestorConsequential.interfacesBasedOnSelf.add(self)
-
- # Deal with interfaces marked [Unforgeable], now that we have our full
- # member list, except unforgeables pulled in from parents. We want to
- # do this before we set "originatingInterface" on our unforgeable
- # members.
- if self.getExtendedAttribute("Unforgeable"):
- # Check that the interface already has all the things the
- # spec would otherwise require us to synthesize and is
- # missing the ones we plan to synthesize.
- if not any(m.isMethod() and m.isStringifier() for m in self.members):
- raise WebIDLError("Unforgeable interface %s does not have a "
- "stringifier" % self.identifier.name,
- [self.location])
-
- for m in self.members:
- if ((m.isMethod() and m.isJsonifier()) or
- m.identifier.name == "toJSON"):
- raise WebIDLError("Unforgeable interface %s has a "
- "jsonifier so we won't be able to add "
- "one ourselves" % self.identifier.name,
- [self.location, m.location])
-
- if m.identifier.name == "valueOf" and not m.isStatic():
- raise WebIDLError("Unforgeable interface %s has a valueOf "
- "member so we won't be able to add one "
- "ourselves" % self.identifier.name,
- [self.location, m.location])
-
- for member in self.members:
- if ((member.isAttr() or member.isMethod()) and
- member.isUnforgeable() and
- not hasattr(member, "originatingInterface")):
- member.originatingInterface = self
-
- # Compute slot indices for our members before we pull in
- # unforgeable members from our parent.
- for member in self.members:
- if (member.isAttr() and
- (member.getExtendedAttribute("StoreInSlot") or
- member.getExtendedAttribute("Cached"))):
- member.slotIndex = self.totalMembersInSlots
- self.totalMembersInSlots += 1
- if member.getExtendedAttribute("StoreInSlot"):
- self._ownMembersInSlots += 1
-
- if self.parent:
- # Make sure we don't shadow any of the [Unforgeable] attributes on
- # our ancestor interfaces. We don't have to worry about
- # consequential interfaces here, because those have already been
- # imported into the relevant .members lists. And we don't have to
- # worry about anything other than our parent, because it has already
- # imported its ancestors unforgeable attributes into its member
- # list.
- for unforgeableMember in (member for member in self.parent.members if
- (member.isAttr() or member.isMethod()) and
- member.isUnforgeable()):
- shadows = [ m for m in self.members if
- (m.isAttr() or m.isMethod()) and
- not m.isStatic() and
- m.identifier.name == unforgeableMember.identifier.name ]
- if len(shadows) != 0:
- locs = [unforgeableMember.location] + [ s.location for s
- in shadows ]
- raise WebIDLError("Interface %s shadows [Unforgeable] "
- "members of %s" %
- (self.identifier.name,
- ancestor.identifier.name),
- locs)
- # And now just stick it in our members, since we won't be
- # inheriting this down the proto chain. If we really cared we
- # could try to do something where we set up the unforgeable
- # attributes/methods of ancestor interfaces, with their
- # corresponding getters, on our interface, but that gets pretty
- # complicated and seems unnecessary.
- self.members.append(unforgeableMember)
-
- # Ensure that there's at most one of each {named,indexed}
- # {getter,setter,creator,deleter}, at most one stringifier,
- # and at most one legacycaller. Note that this last is not
- # quite per spec, but in practice no one overloads
- # legacycallers.
- specialMembersSeen = {}
- for member in self.members:
- if not member.isMethod():
- continue
-
- if member.isGetter():
- memberType = "getters"
- elif member.isSetter():
- memberType = "setters"
- elif member.isCreator():
- memberType = "creators"
- elif member.isDeleter():
- memberType = "deleters"
- elif member.isStringifier():
- memberType = "stringifiers"
- elif member.isJsonifier():
- memberType = "jsonifiers"
- elif member.isLegacycaller():
- memberType = "legacycallers"
- else:
- continue
-
- if (memberType != "stringifiers" and memberType != "legacycallers" and
- memberType != "jsonifiers"):
- if member.isNamed():
- memberType = "named " + memberType
- else:
- assert member.isIndexed()
- memberType = "indexed " + memberType
-
- if memberType in specialMembersSeen:
- raise WebIDLError("Multiple " + memberType + " on %s" % (self),
- [self.location,
- specialMembersSeen[memberType].location,
- member.location])
-
- specialMembersSeen[memberType] = member
-
- if self._isOnGlobalProtoChain:
- # Make sure we have no named setters, creators, or deleters
- for memberType in ["setter", "creator", "deleter"]:
- memberId = "named " + memberType + "s"
- if memberId in specialMembersSeen:
- raise WebIDLError("Interface with [Global] has a named %s" %
- memberType,
- [self.location,
- specialMembersSeen[memberId].location])
- # Make sure we're not [OverrideBuiltins]
- if self.getExtendedAttribute("OverrideBuiltins"):
- raise WebIDLError("Interface with [Global] also has "
- "[OverrideBuiltins]",
- [self.location])
- # Mark all of our ancestors as being on the global's proto chain too
- parent = self.parent
- while parent:
- # Must not inherit from an interface with [OverrideBuiltins]
- if parent.getExtendedAttribute("OverrideBuiltins"):
- raise WebIDLError("Interface with [Global] inherits from "
- "interface with [OverrideBuiltins]",
- [self.location, parent.location])
- parent._isOnGlobalProtoChain = True
- parent = parent.parent
-
- def validate(self):
- # We don't support consequential unforgeable interfaces. Need to check
- # this here, becaue in finish() an interface might not know yet that
- # it's consequential.
- if self.getExtendedAttribute("Unforgeable") and self.isConsequential():
- raise WebIDLError(
- "%s is an unforgeable consequential interface" %
- self.identifier.name,
- [self.location] +
- list(i.location for i in
- (self.interfacesBasedOnSelf - { self }) ))
-
- # We also don't support inheriting from unforgeable interfaces.
- if self.getExtendedAttribute("Unforgeable") and self.hasChildInterfaces():
- raise WebIDLError("%s is an unforgeable ancestor interface" %
- self.identifier.name,
- [self.location] +
- list(i.location for i in
- self.interfacesBasedOnSelf if i.parent == self))
-
-
- for member in self.members:
- member.validate()
-
- # Check that PutForwards refers to another attribute and that no
- # cycles exist in forwarded assignments.
- if member.isAttr():
- iface = self
- attr = member
- putForwards = attr.getExtendedAttribute("PutForwards")
- if putForwards and self.isCallback():
- raise WebIDLError("[PutForwards] used on an attribute "
- "on interface %s which is a callback "
- "interface" % self.identifier.name,
- [self.location, member.location])
-
- while putForwards is not None:
- forwardIface = attr.type.unroll().inner
- fowardAttr = None
-
- for forwardedMember in forwardIface.members:
- if (not forwardedMember.isAttr() or
- forwardedMember.identifier.name != putForwards[0]):
- continue
- if forwardedMember == member:
- raise WebIDLError("Cycle detected in forwarded "
- "assignments for attribute %s on "
- "%s" %
- (member.identifier.name, self),
- [member.location])
- fowardAttr = forwardedMember
- break
-
- if fowardAttr is None:
- raise WebIDLError("Attribute %s on %s forwards to "
- "missing attribute %s" %
- (attr.identifier.name, iface, putForwards),
- [attr.location])
-
- iface = forwardIface
- attr = fowardAttr
- putForwards = attr.getExtendedAttribute("PutForwards")
-
- if (self.getExtendedAttribute("Pref") and
- self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
- raise WebIDLError("[Pref] used on an member that is not %s-only" %
- self.parentScope.primaryGlobalName,
- [self.location])
-
-
- def isInterface(self):
- return True
-
- def isExternal(self):
- return False
-
- def setIsConsequentialInterfaceOf(self, other):
- self._consequential = True
- self.interfacesBasedOnSelf.add(other)
-
- def isConsequential(self):
- return self._consequential
-
- def setCallback(self, value):
- self._callback = value
-
- def isCallback(self):
- return self._callback
-
- def isSingleOperationInterface(self):
- assert self.isCallback() or self.isJSImplemented()
- return (
- # JS-implemented things should never need the
- # this-handling weirdness of single-operation interfaces.
- not self.isJSImplemented() and
- # Not inheriting from another interface
- not self.parent and
- # No consequential interfaces
- len(self.getConsequentialInterfaces()) == 0 and
- # No attributes of any kinds
- not any(m.isAttr() for m in self.members) and
- # There is at least one regular operation, and all regular
- # operations have the same identifier
- len(set(m.identifier.name for m in self.members if
- m.isMethod() and not m.isStatic())) == 1)
-
- def inheritanceDepth(self):
- depth = 0
- parent = self.parent
- while parent:
- depth = depth + 1
- parent = parent.parent
- return depth
-
- def hasConstants(self):
- return any(m.isConst() for m in self.members)
-
- def hasInterfaceObject(self):
- if self.isCallback():
- return self.hasConstants()
- return not hasattr(self, "_noInterfaceObject")
-
- def hasInterfacePrototypeObject(self):
- return not self.isCallback() and self.getUserData('hasConcreteDescendant', False)
-
- def addExtendedAttributes(self, attrs):
- for attr in attrs:
- identifier = attr.identifier()
-
- # Special cased attrs
- if identifier == "TreatNonCallableAsNull":
- raise WebIDLError("TreatNonCallableAsNull cannot be specified on interfaces",
- [attr.location, self.location])
- if identifier == "TreatNonObjectAsNull":
- raise WebIDLError("TreatNonObjectAsNull cannot be specified on interfaces",
- [attr.location, self.location])
- elif identifier == "NoInterfaceObject":
- if not attr.noArguments():
- raise WebIDLError("[NoInterfaceObject] must take no arguments",
- [attr.location])
-
- if self.ctor():
- raise WebIDLError("Constructor and NoInterfaceObject are incompatible",
- [self.location])
-
- self._noInterfaceObject = True
- elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor":
- if identifier == "Constructor" and not self.hasInterfaceObject():
- raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
- [self.location])
-
- if identifier == "NamedConstructor" and not attr.hasValue():
- raise WebIDLError("NamedConstructor must either take an identifier or take a named argument list",
- [attr.location])
-
- if identifier == "ChromeConstructor" and not self.hasInterfaceObject():
- raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
- [self.location])
-
- args = attr.args() if attr.hasArgs() else []
-
- retType = IDLWrapperType(self.location, self)
-
- if identifier == "Constructor" or identifier == "ChromeConstructor":
- name = "constructor"
- allowForbidden = True
- else:
- name = attr.value()
- allowForbidden = False
-
- methodIdentifier = IDLUnresolvedIdentifier(self.location, name,
- allowForbidden=allowForbidden)
-
- method = IDLMethod(self.location, methodIdentifier, retType,
- args, static=True)
- # Constructors are always NewObject and are always
- # assumed to be able to throw (since there's no way to
- # indicate otherwise) and never have any other
- # extended attributes.
- method.addExtendedAttributes(
- [IDLExtendedAttribute(self.location, ("NewObject",)),
- IDLExtendedAttribute(self.location, ("Throws",))])
- if identifier == "ChromeConstructor":
- method.addExtendedAttributes(
- [IDLExtendedAttribute(self.location, ("ChromeOnly",))])
-
- if identifier == "Constructor" or identifier == "ChromeConstructor":
- method.resolve(self)
- else:
- # We need to detect conflicts for NamedConstructors across
- # interfaces. We first call resolve on the parentScope,
- # which will merge all NamedConstructors with the same
- # identifier accross interfaces as overloads.
- method.resolve(self.parentScope)
-
- # Then we look up the identifier on the parentScope. If the
- # result is the same as the method we're adding then it
- # hasn't been added as an overload and it's the first time
- # we've encountered a NamedConstructor with that identifier.
- # If the result is not the same as the method we're adding
- # then it has been added as an overload and we need to check
- # whether the result is actually one of our existing
- # NamedConstructors.
- newMethod = self.parentScope.lookupIdentifier(method.identifier)
- if newMethod == method:
- self.namedConstructors.append(method)
- elif not newMethod in self.namedConstructors:
- raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface",
- [method.location, newMethod.location])
- elif (identifier == "ArrayClass"):
- if not attr.noArguments():
- raise WebIDLError("[ArrayClass] must take no arguments",
- [attr.location])
- if self.parent:
- raise WebIDLError("[ArrayClass] must not be specified on "
- "an interface with inherited interfaces",
- [attr.location, self.location])
- elif (identifier == "ExceptionClass"):
- if not attr.noArguments():
- raise WebIDLError("[ExceptionClass] must take no arguments",
- [attr.location])
- if self.parent:
- raise WebIDLError("[ExceptionClass] must not be specified on "
- "an interface with inherited interfaces",
- [attr.location, self.location])
- elif identifier == "Global":
- if attr.hasValue():
- self.globalNames = [ attr.value() ]
- elif attr.hasArgs():
- self.globalNames = attr.args()
- else:
- self.globalNames = [ self.identifier.name ]
- self.parentScope.globalNames.update(self.globalNames)
- for globalName in self.globalNames:
- self.parentScope.globalNameMapping[globalName].add(self.identifier.name)
- self._isOnGlobalProtoChain = True
- elif identifier == "PrimaryGlobal":
- if not attr.noArguments():
- raise WebIDLError("[PrimaryGlobal] must take no arguments",
- [attr.location])
- if self.parentScope.primaryGlobalAttr is not None:
- raise WebIDLError(
- "[PrimaryGlobal] specified twice",
- [attr.location,
- self.parentScope.primaryGlobalAttr.location])
- self.parentScope.primaryGlobalAttr = attr
- self.parentScope.primaryGlobalName = self.identifier.name
- self.parentScope.globalNames.add(self.identifier.name)
- self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name)
- self._isOnGlobalProtoChain = True
- elif (identifier == "NeedNewResolve" or
- identifier == "OverrideBuiltins" or
- identifier == "ChromeOnly" or
- identifier == "Unforgeable" or
- identifier == "LegacyEventInit"):
- # Known extended attributes that do not take values
- if not attr.noArguments():
- raise WebIDLError("[%s] must take no arguments" % identifier,
- [attr.location])
- elif identifier == "Exposed":
- convertExposedAttrToGlobalNameSet(attr,
- self._exposureGlobalNames)
- elif (identifier == "Pref" or
- identifier == "JSImplementation" or
- identifier == "HeaderFile" or
- identifier == "NavigatorProperty" or
- identifier == "AvailableIn" or
- identifier == "Func" or
- identifier == "CheckPermissions"):
- # Known extended attributes that take a string value
- if not attr.hasValue():
- raise WebIDLError("[%s] must have a value" % identifier,
- [attr.location])
- else:
- raise WebIDLError("Unknown extended attribute %s on interface" % identifier,
- [attr.location])
-
- attrlist = attr.listValue()
- self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True
-
- def addImplementedInterface(self, implementedInterface):
- assert(isinstance(implementedInterface, IDLInterface))
- self.implementedInterfaces.add(implementedInterface)
-
- def getInheritedInterfaces(self):
- """
- Returns a list of the interfaces this interface inherits from
- (not including this interface itself). The list is in order
- from most derived to least derived.
- """
- assert(self._finished)
- if not self.parent:
- return []
- parentInterfaces = self.parent.getInheritedInterfaces()
- parentInterfaces.insert(0, self.parent)
- return parentInterfaces
-
- def getConsequentialInterfaces(self):
- assert(self._finished)
- # The interfaces we implement directly
- consequentialInterfaces = set(self.implementedInterfaces)
-
- # And their inherited interfaces
- for iface in self.implementedInterfaces:
- consequentialInterfaces |= set(iface.getInheritedInterfaces())
-
- # And now collect up the consequential interfaces of all of those
- temp = set()
- for iface in consequentialInterfaces:
- temp |= iface.getConsequentialInterfaces()
-
- return consequentialInterfaces | temp
-
- def findInterfaceLoopPoint(self, otherInterface):
- """
- Finds an interface, amongst our ancestors and consequential interfaces,
- that inherits from otherInterface or implements otherInterface
- directly. If there is no such interface, returns None.
- """
- if self.parent:
- if self.parent == otherInterface:
- return self
- loopPoint = self.parent.findInterfaceLoopPoint(otherInterface)
- if loopPoint:
- return loopPoint
- if otherInterface in self.implementedInterfaces:
- return self
- for iface in self.implementedInterfaces:
- loopPoint = iface.findInterfaceLoopPoint(otherInterface)
- if loopPoint:
- return loopPoint
- return None
-
- def getExtendedAttribute(self, name):
- return self._extendedAttrDict.get(name, None)
-
- def setNonPartial(self, location, parent, members):
- assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
- if self._isKnownNonPartial:
- raise WebIDLError("Two non-partial definitions for the "
- "same interface",
- [location, self.location])
- self._isKnownNonPartial = True
- # Now make it look like we were parsed at this new location, since
- # that's the place where the interface is "really" defined
- self.location = location
- assert not self.parent
- self.parent = parent
- # Put the new members at the beginning
- self.members = members + self.members
-
- def addPartialInterface(self, partial):
- assert self.identifier.name == partial.identifier.name
- self._partialInterfaces.append(partial)
-
- def getJSImplementation(self):
- classId = self.getExtendedAttribute("JSImplementation")
- if not classId:
- return classId
- assert isinstance(classId, list)
- assert len(classId) == 1
- return classId[0]
-
- def isJSImplemented(self):
- return bool(self.getJSImplementation())
-
- def getNavigatorProperty(self):
- naviProp = self.getExtendedAttribute("NavigatorProperty")
- if not naviProp:
- return None
- assert len(naviProp) == 1
- assert isinstance(naviProp, list)
- assert len(naviProp[0]) != 0
- return naviProp[0]
-
- def hasChildInterfaces(self):
- return self._hasChildInterfaces
-
- def isOnGlobalProtoChain(self):
- return self._isOnGlobalProtoChain
-
- def _getDependentObjects(self):
- deps = set(self.members)
- deps.union(self.implementedInterfaces)
- if self.parent:
- deps.add(self.parent)
- return deps
-
- def hasMembersInSlots(self):
- return self._ownMembersInSlots != 0
-
-class IDLDictionary(IDLObjectWithScope):
- def __init__(self, location, parentScope, name, parent, members):
- assert isinstance(parentScope, IDLScope)
- assert isinstance(name, IDLUnresolvedIdentifier)
- assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
-
- self.parent = parent
- self._finished = False
- self.members = list(members)
-
- IDLObjectWithScope.__init__(self, location, parentScope, name)
-
- def __str__(self):
- return "Dictionary '%s'" % self.identifier.name
-
- def isDictionary(self):
- return True;
-
- def finish(self, scope):
- if self._finished:
- return
-
- self._finished = True
-
- if self.parent:
- assert isinstance(self.parent, IDLIdentifierPlaceholder)
- oldParent = self.parent
- self.parent = self.parent.finish(scope)
- if not isinstance(self.parent, IDLDictionary):
- raise WebIDLError("Dictionary %s has parent that is not a dictionary" %
- self.identifier.name,
- [oldParent.location, self.parent.location])
-
- # Make sure the parent resolves all its members before we start
- # looking at them.
- self.parent.finish(scope)
-
- for member in self.members:
- member.resolve(self)
- if not member.isComplete():
- member.complete(scope)
- assert member.type.isComplete()
-
- # Members of a dictionary are sorted in lexicographic order
- self.members.sort(cmp=cmp, key=lambda x: x.identifier.name)
-
- inheritedMembers = []
- ancestor = self.parent
- while ancestor:
- if ancestor == self:
- raise WebIDLError("Dictionary %s has itself as an ancestor" %
- self.identifier.name,
- [self.identifier.location])
- inheritedMembers.extend(ancestor.members)
- ancestor = ancestor.parent
-
- # Catch name duplication
- for inheritedMember in inheritedMembers:
- for member in self.members:
- if member.identifier.name == inheritedMember.identifier.name:
- raise WebIDLError("Dictionary %s has two members with name %s" %
- (self.identifier.name, member.identifier.name),
- [member.location, inheritedMember.location])
-
- def validate(self):
- def typeContainsDictionary(memberType, dictionary):
- """
- Returns a tuple whose:
-
- - First element is a Boolean value indicating whether
- memberType contains dictionary.
-
- - Second element is:
- A list of locations that leads from the type that was passed in
- the memberType argument, to the dictionary being validated,
- if the boolean value in the first element is True.
-
- None, if the boolean value in the first element is False.
- """
-
- if (memberType.nullable() or
- memberType.isArray() or
- memberType.isSequence() or
- memberType.isMozMap()):
- return typeContainsDictionary(memberType.inner, dictionary)
-
- if memberType.isDictionary():
- if memberType.inner == dictionary:
- return (True, [memberType.location])
-
- (contains, locations) = dictionaryContainsDictionary(memberType.inner, \
- dictionary)
- if contains:
- return (True, [memberType.location] + locations)
-
- if memberType.isUnion():
- for member in memberType.flatMemberTypes:
- (contains, locations) = typeContainsDictionary(member, dictionary)
- if contains:
- return (True, locations)
-
- return (False, None)
-
- def dictionaryContainsDictionary(dictMember, dictionary):
- for member in dictMember.members:
- (contains, locations) = typeContainsDictionary(member.type, dictionary)
- if contains:
- return (True, [member.location] + locations)
-
- if dictMember.parent:
- if dictMember.parent == dictionary:
- return (True, [dictMember.location])
- else:
- (contains, locations) = dictionaryContainsDictionary(dictMember.parent, dictionary)
- if contains:
- return (True, [dictMember.location] + locations)
-
- return (False, None)
-
- for member in self.members:
- if member.type.isDictionary() and member.type.nullable():
- raise WebIDLError("Dictionary %s has member with nullable "
- "dictionary type" % self.identifier.name,
- [member.location])
- (contains, locations) = typeContainsDictionary(member.type, self)
- if contains:
- raise WebIDLError("Dictionary %s has member with itself as type." %
- self.identifier.name,
- [member.location] + locations)
-
- def addExtendedAttributes(self, attrs):
- assert len(attrs) == 0
-
- def _getDependentObjects(self):
- deps = set(self.members)
- if (self.parent):
- deps.add(self.parent)
- return deps
-
-class IDLEnum(IDLObjectWithIdentifier):
- def __init__(self, location, parentScope, name, values):
- assert isinstance(parentScope, IDLScope)
- assert isinstance(name, IDLUnresolvedIdentifier)
-
- if len(values) != len(set(values)):
- raise WebIDLError("Enum %s has multiple identical strings" % name.name,
- [location])
-
- IDLObjectWithIdentifier.__init__(self, location, parentScope, name)
- self._values = values
-
- def values(self):
- return self._values
-
- def finish(self, scope):
- pass
-
- def validate(self):
- pass
-
- def isEnum(self):
- return True
-
- def addExtendedAttributes(self, attrs):
- assert len(attrs) == 0
-
- def _getDependentObjects(self):
- return set()
-
-class IDLType(IDLObject):
- Tags = enum(
- # The integer types
- 'int8',
- 'uint8',
- 'int16',
- 'uint16',
- 'int32',
- 'uint32',
- 'int64',
- 'uint64',
- # Additional primitive types
- 'bool',
- 'unrestricted_float',
- 'float',
- 'unrestricted_double',
- # "double" last primitive type to match IDLBuiltinType
- 'double',
- # Other types
- 'any',
- 'domstring',
- 'bytestring',
- 'scalarvaluestring',
- 'object',
- 'date',
- 'void',
- # Funny stuff
- 'interface',
- 'dictionary',
- 'enum',
- 'callback',
- 'union',
- 'sequence',
- 'mozmap',
- 'array'
- )
-
- def __init__(self, location, name):
- IDLObject.__init__(self, location)
- self.name = name
- self.builtin = False
-
- def __eq__(self, other):
- return other and self.builtin == other.builtin and self.name == other.name
-
- def __ne__(self, other):
- return not self == other
-
- def __str__(self):
- return str(self.name)
-
- def isType(self):
- return True
-
- def nullable(self):
- return False
-
- def isPrimitive(self):
- return False
-
- def isBoolean(self):
- return False
-
- def isNumeric(self):
- return False
-
- def isString(self):
- return False
-
- def isByteString(self):
- return False
-
- def isDOMString(self):
- return False
-
- def isScalarValueString(self):
- return False
-
- def isVoid(self):
- return self.name == "Void"
-
- def isSequence(self):
- return False
-
- def isMozMap(self):
- return False
-
- def isArray(self):
- return False
-
- def isArrayBuffer(self):
- return False
-
- def isArrayBufferView(self):
- return False
-
- def isTypedArray(self):
- return False
-
- def isCallbackInterface(self):
- return False
-
- def isNonCallbackInterface(self):
- return False
-
- def isGeckoInterface(self):
- """ Returns a boolean indicating whether this type is an 'interface'
- type that is implemented in Gecko. At the moment, this returns
- true for all interface types that are not types from the TypedArray
- spec."""
- return self.isInterface() and not self.isSpiderMonkeyInterface()
-
- def isSpiderMonkeyInterface(self):
- """ Returns a boolean indicating whether this type is an 'interface'
- type that is implemented in Spidermonkey. At the moment, this
- only returns true for the types from the TypedArray spec. """
- return self.isInterface() and (self.isArrayBuffer() or \
- self.isArrayBufferView() or \
- self.isTypedArray())
-
- def isDictionary(self):
- return False
-
- def isInterface(self):
- return False
-
- def isAny(self):
- return self.tag() == IDLType.Tags.any
-
- def isDate(self):
- return self.tag() == IDLType.Tags.date
-
- def isObject(self):
- return self.tag() == IDLType.Tags.object
-
- def isPromise(self):
- return False
-
- def isComplete(self):
- return True
-
- def includesRestrictedFloat(self):
- return False
-
- def isFloat(self):
- return False
-
- def isUnrestricted(self):
- # Should only call this on float types
- assert self.isFloat()
-
- def isSerializable(self):
- return False
-
- def tag(self):
- assert False # Override me!
-
- def treatNonCallableAsNull(self):
- assert self.tag() == IDLType.Tags.callback
- return self.nullable() and self.inner._treatNonCallableAsNull
-
- def treatNonObjectAsNull(self):
- assert self.tag() == IDLType.Tags.callback
- return self.nullable() and self.inner._treatNonObjectAsNull
-
- def addExtendedAttributes(self, attrs):
- assert len(attrs) == 0
-
- def resolveType(self, parentScope):
- pass
-
- def unroll(self):
- return self
-
- def isDistinguishableFrom(self, other):
- raise TypeError("Can't tell whether a generic type is or is not "
- "distinguishable from other things")
-
- def isExposedInAllOf(self, exposureSet):
- return True
-
-class IDLUnresolvedType(IDLType):
- """
- Unresolved types are interface types
- """
-
- def __init__(self, location, name, promiseInnerType=None):
- IDLType.__init__(self, location, name)
- self._promiseInnerType = promiseInnerType
-
- def isComplete(self):
- return False
-
- def complete(self, scope):
- obj = None
- try:
- obj = scope._lookupIdentifier(self.name)
- except:
- raise WebIDLError("Unresolved type '%s'." % self.name,
- [self.location])
-
- assert obj
- if obj.isType():
- # obj itself might not be complete; deal with that.
- assert obj != self
- if not obj.isComplete():
- obj = obj.complete(scope)
- return obj
-
- if self._promiseInnerType and not self._promiseInnerType.isComplete():
- self._promiseInnerType = self._promiseInnerType.complete(scope)
-
- name = self.name.resolve(scope, None)
- return IDLWrapperType(self.location, obj, self._promiseInnerType)
-
- def isDistinguishableFrom(self, other):
- raise TypeError("Can't tell whether an unresolved type is or is not "
- "distinguishable from other things")
-
-class IDLNullableType(IDLType):
- def __init__(self, location, innerType):
- assert not innerType.isVoid()
- assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
-
- IDLType.__init__(self, location, innerType.name)
- self.inner = innerType
- self.builtin = False
-
- def __eq__(self, other):
- return isinstance(other, IDLNullableType) and self.inner == other.inner
-
- def __str__(self):
- return self.inner.__str__() + "OrNull"
-
- def nullable(self):
- return True
-
- def isCallback(self):
- return self.inner.isCallback()
-
- def isPrimitive(self):
- return self.inner.isPrimitive()
-
- def isBoolean(self):
- return self.inner.isBoolean()
-
- def isNumeric(self):
- return self.inner.isNumeric()
-
- def isString(self):
- return self.inner.isString()
-
- def isByteString(self):
- return self.inner.isByteString()
-
- def isDOMString(self):
- return self.inner.isDOMString()
-
- def isScalarValueString(self):
- return self.inner.isScalarValueString()
-
- def isFloat(self):
- return self.inner.isFloat()
-
- def isUnrestricted(self):
- return self.inner.isUnrestricted()
-
- def includesRestrictedFloat(self):
- return self.inner.includesRestrictedFloat()
-
- def isInteger(self):
- return self.inner.isInteger()
-
- def isVoid(self):
- return False
-
- def isSequence(self):
- return self.inner.isSequence()
-
- def isMozMap(self):
- return self.inner.isMozMap()
-
- def isArray(self):
- return self.inner.isArray()
-
- def isArrayBuffer(self):
- return self.inner.isArrayBuffer()
-
- def isArrayBufferView(self):
- return self.inner.isArrayBufferView()
-
- def isTypedArray(self):
- return self.inner.isTypedArray()
-
- def isDictionary(self):
- return self.inner.isDictionary()
-
- def isInterface(self):
- return self.inner.isInterface()
-
- def isCallbackInterface(self):
- return self.inner.isCallbackInterface()
-
- def isNonCallbackInterface(self):
- return self.inner.isNonCallbackInterface()
-
- def isEnum(self):
- return self.inner.isEnum()
-
- def isUnion(self):
- return self.inner.isUnion()
-
- def isSerializable(self):
- return self.inner.isSerializable()
-
- def tag(self):
- return self.inner.tag()
-
- def resolveType(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- self.inner.resolveType(parentScope)
-
- def isComplete(self):
- return self.inner.isComplete()
-
- def complete(self, scope):
- self.inner = self.inner.complete(scope)
- if self.inner.nullable():
- raise WebIDLError("The inner type of a nullable type must not be "
- "a nullable type",
- [self.location, self.inner.location])
- if self.inner.isUnion():
- if self.inner.hasNullableType:
- raise WebIDLError("The inner type of a nullable type must not "
- "be a union type that itself has a nullable "
- "type as a member type", [self.location])
-
- self.name = self.inner.name
- return self
-
- def unroll(self):
- return self.inner.unroll()
-
- def isDistinguishableFrom(self, other):
- if (other.nullable() or (other.isUnion() and other.hasNullableType) or
- other.isDictionary()):
- # Can't tell which type null should become
- return False
- return self.inner.isDistinguishableFrom(other)
-
- def _getDependentObjects(self):
- return self.inner._getDependentObjects()
-
-class IDLSequenceType(IDLType):
- def __init__(self, location, parameterType):
- assert not parameterType.isVoid()
-
- IDLType.__init__(self, location, parameterType.name)
- self.inner = parameterType
- self.builtin = False
-
- def __eq__(self, other):
- return isinstance(other, IDLSequenceType) and self.inner == other.inner
-
- def __str__(self):
- return self.inner.__str__() + "Sequence"
-
- def nullable(self):
- return False
-
- def isPrimitive(self):
- return False;
-
- def isString(self):
- return False;
-
- def isByteString(self):
- return False
-
- def isDOMString(self):
- return False
-
- def isScalarValueString(self):
- return False
-
- def isVoid(self):
- return False
-
- def isSequence(self):
- return True
-
- def isArray(self):
- return False
-
- def isDictionary(self):
- return False
-
- def isInterface(self):
- return False
-
- def isEnum(self):
- return False
-
- def isSerializable(self):
- return self.inner.isSerializable()
-
- def includesRestrictedFloat(self):
- return self.inner.includesRestrictedFloat()
-
- def tag(self):
- return IDLType.Tags.sequence
-
- def resolveType(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- self.inner.resolveType(parentScope)
-
- def isComplete(self):
- return self.inner.isComplete()
-
- def complete(self, scope):
- self.inner = self.inner.complete(scope)
- self.name = self.inner.name
- return self
-
- def unroll(self):
- return self.inner.unroll()
-
- def isDistinguishableFrom(self, other):
- if other.isUnion():
- # Just forward to the union; it'll deal
- return other.isDistinguishableFrom(self)
- return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isDate() or other.isNonCallbackInterface() or other.isMozMap())
-
- def _getDependentObjects(self):
- return self.inner._getDependentObjects()
-
-class IDLMozMapType(IDLType):
- # XXXbz This is pretty similar to IDLSequenceType in various ways.
- # And maybe to IDLNullableType. Should we have a superclass for
- # "type containing this other type"? Bug 1015318.
- def __init__(self, location, parameterType):
- assert not parameterType.isVoid()
-
- IDLType.__init__(self, location, parameterType.name)
- self.inner = parameterType
- self.builtin = False
-
- def __eq__(self, other):
- return isinstance(other, IDLMozMapType) and self.inner == other.inner
-
- def __str__(self):
- return self.inner.__str__() + "MozMap"
-
- def isMozMap(self):
- return True
-
- def includesRestrictedFloat(self):
- return self.inner.includesRestrictedFloat()
-
- def tag(self):
- return IDLType.Tags.mozmap
-
- def resolveType(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- self.inner.resolveType(parentScope)
-
- def isComplete(self):
- return self.inner.isComplete()
-
- def complete(self, scope):
- self.inner = self.inner.complete(scope)
- self.name = self.inner.name
- return self
-
- def unroll(self):
- # We do not unroll our inner. Just stop at ourselves. That
- # lets us add headers for both ourselves and our inner as
- # needed.
- return self
-
- def isDistinguishableFrom(self, other):
- if other.isUnion():
- # Just forward to the union; it'll deal
- return other.isDistinguishableFrom(self)
- return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isDate() or other.isNonCallbackInterface() or other.isSequence())
-
- def isExposedInAllOf(self, exposureSet):
- return self.inner.unroll().isExposedInAllOf(exposureSet)
-
- def _getDependentObjects(self):
- return self.inner._getDependentObjects()
-
-class IDLUnionType(IDLType):
- def __init__(self, location, memberTypes):
- IDLType.__init__(self, location, "")
- self.memberTypes = memberTypes
- self.hasNullableType = False
- self.hasDictionaryType = False
- self.flatMemberTypes = None
- self.builtin = False
-
- def __eq__(self, other):
- return isinstance(other, IDLUnionType) and self.memberTypes == other.memberTypes
-
- def isVoid(self):
- return False
-
- def isUnion(self):
- return True
-
- def isSerializable(self):
- return all(m.isSerializable() for m in self.memberTypes)
-
- def includesRestrictedFloat(self):
- return any(t.includesRestrictedFloat() for t in self.memberTypes)
-
- def tag(self):
- return IDLType.Tags.union
-
- def resolveType(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- for t in self.memberTypes:
- t.resolveType(parentScope)
-
- def isComplete(self):
- return self.flatMemberTypes is not None
-
- def complete(self, scope):
- def typeName(type):
- if isinstance(type, IDLNullableType):
- return typeName(type.inner) + "OrNull"
- if isinstance(type, IDLWrapperType):
- return typeName(type._identifier.object())
- if isinstance(type, IDLObjectWithIdentifier):
- return typeName(type.identifier)
- if (isinstance(type, IDLType) and
- (type.isArray() or type.isSequence() or type.isMozMap)):
- return str(type)
- return type.name
-
- for (i, type) in enumerate(self.memberTypes):
- if not type.isComplete():
- self.memberTypes[i] = type.complete(scope)
-
- self.name = "Or".join(typeName(type) for type in self.memberTypes)
- self.flatMemberTypes = list(self.memberTypes)
- i = 0
- while i < len(self.flatMemberTypes):
- if self.flatMemberTypes[i].nullable():
- if self.hasNullableType:
- raise WebIDLError("Can't have more than one nullable types in a union",
- [nullableType.location, self.flatMemberTypes[i].location])
- if self.hasDictionaryType:
- raise WebIDLError("Can't have a nullable type and a "
- "dictionary type in a union",
- [dictionaryType.location,
- self.flatMemberTypes[i].location])
- self.hasNullableType = True
- nullableType = self.flatMemberTypes[i]
- self.flatMemberTypes[i] = self.flatMemberTypes[i].inner
- continue
- if self.flatMemberTypes[i].isDictionary():
- if self.hasNullableType:
- raise WebIDLError("Can't have a nullable type and a "
- "dictionary type in a union",
- [nullableType.location,
- self.flatMemberTypes[i].location])
- self.hasDictionaryType = True
- dictionaryType = self.flatMemberTypes[i]
- elif self.flatMemberTypes[i].isUnion():
- self.flatMemberTypes[i:i + 1] = self.flatMemberTypes[i].memberTypes
- continue
- i += 1
-
- for (i, t) in enumerate(self.flatMemberTypes[:-1]):
- for u in self.flatMemberTypes[i + 1:]:
- if not t.isDistinguishableFrom(u):
- raise WebIDLError("Flat member types of a union should be "
- "distinguishable, " + str(t) + " is not "
- "distinguishable from " + str(u),
- [self.location, t.location, u.location])
-
- return self
-
- def isDistinguishableFrom(self, other):
- if self.hasNullableType and other.nullable():
- # Can't tell which type null should become
- return False
- if other.isUnion():
- otherTypes = other.unroll().memberTypes
- else:
- otherTypes = [other]
- # For every type in otherTypes, check that it's distinguishable from
- # every type in our types
- for u in otherTypes:
- if any(not t.isDistinguishableFrom(u) for t in self.memberTypes):
- return False
- return True
-
- def isExposedInAllOf(self, exposureSet):
- # We could have different member types in different globals. Just make sure that each thing in exposureSet has one of our member types exposed in it.
- for globalName in exposureSet:
- if not any(t.unroll().isExposedInAllOf(set([globalName])) for t
- in self.flatMemberTypes):
- return False
- return True
-
- def _getDependentObjects(self):
- return set(self.memberTypes)
-
-class IDLArrayType(IDLType):
- def __init__(self, location, parameterType):
- assert not parameterType.isVoid()
- if parameterType.isSequence():
- raise WebIDLError("Array type cannot parameterize over a sequence type",
- [location])
- if parameterType.isMozMap():
- raise WebIDLError("Array type cannot parameterize over a MozMap type",
- [location])
- if parameterType.isDictionary():
- raise WebIDLError("Array type cannot parameterize over a dictionary type",
- [location])
-
- IDLType.__init__(self, location, parameterType.name)
- self.inner = parameterType
- self.builtin = False
-
- def __eq__(self, other):
- return isinstance(other, IDLArrayType) and self.inner == other.inner
-
- def __str__(self):
- return self.inner.__str__() + "Array"
-
- def nullable(self):
- return False
-
- def isPrimitive(self):
- return False
-
- def isString(self):
- return False
-
- def isByteString(self):
- return False
-
- def isDOMString(self):
- return False
-
- def isScalarValueString(self):
- return False
-
- def isVoid(self):
- return False
-
- def isSequence(self):
- assert not self.inner.isSequence()
- return False
-
- def isArray(self):
- return True
-
- def isDictionary(self):
- assert not self.inner.isDictionary()
- return False
-
- def isInterface(self):
- return False
-
- def isEnum(self):
- return False
-
- def tag(self):
- return IDLType.Tags.array
-
- def resolveType(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- self.inner.resolveType(parentScope)
-
- def isComplete(self):
- return self.inner.isComplete()
-
- def complete(self, scope):
- self.inner = self.inner.complete(scope)
- self.name = self.inner.name
-
- if self.inner.isDictionary():
- raise WebIDLError("Array type must not contain "
- "dictionary as element type.",
- [self.inner.location])
-
- assert not self.inner.isSequence()
-
- return self
-
- def unroll(self):
- return self.inner.unroll()
-
- def isDistinguishableFrom(self, other):
- if other.isUnion():
- # Just forward to the union; it'll deal
- return other.isDistinguishableFrom(self)
- return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isDate() or other.isNonCallbackInterface())
-
- def _getDependentObjects(self):
- return self.inner._getDependentObjects()
-
-class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
- def __init__(self, location, innerType, name):
- IDLType.__init__(self, location, innerType.name)
-
- identifier = IDLUnresolvedIdentifier(location, name)
-
- IDLObjectWithIdentifier.__init__(self, location, None, identifier)
-
- self.inner = innerType
- self.name = name
- self.builtin = False
-
- def __eq__(self, other):
- return isinstance(other, IDLTypedefType) and self.inner == other.inner
-
- def __str__(self):
- return self.identifier.name
-
- def nullable(self):
- return self.inner.nullable()
-
- def isPrimitive(self):
- return self.inner.isPrimitive()
-
- def isBoolean(self):
- return self.inner.isBoolean()
-
- def isNumeric(self):
- return self.inner.isNumeric()
-
- def isString(self):
- return self.inner.isString()
-
- def isByteString(self):
- return self.inner.isByteString()
-
- def isDOMString(self):
- return self.inner.isDOMString()
-
- def isScalarValueString(self):
- return self.inner.isScalarValueString()
-
- def isVoid(self):
- return self.inner.isVoid()
-
- def isSequence(self):
- return self.inner.isSequence()
-
- def isMozMap(self):
- return self.inner.isMozMap()
-
- def isArray(self):
- return self.inner.isArray()
-
- def isDictionary(self):
- return self.inner.isDictionary()
-
- def isArrayBuffer(self):
- return self.inner.isArrayBuffer()
-
- def isArrayBufferView(self):
- return self.inner.isArrayBufferView()
-
- def isTypedArray(self):
- return self.inner.isTypedArray()
-
- def isInterface(self):
- return self.inner.isInterface()
-
- def isCallbackInterface(self):
- return self.inner.isCallbackInterface()
-
- def isNonCallbackInterface(self):
- return self.inner.isNonCallbackInterface()
-
- def isComplete(self):
- return False
-
- def complete(self, parentScope):
- if not self.inner.isComplete():
- self.inner = self.inner.complete(parentScope)
- assert self.inner.isComplete()
- return self.inner
-
- def finish(self, parentScope):
- # Maybe the IDLObjectWithIdentifier for the typedef should be
- # a separate thing from the type? If that happens, we can
- # remove some hackery around avoiding isInterface() in
- # Configuration.py.
- self.complete(parentScope)
-
- def validate(self):
- pass
-
- # Do we need a resolveType impl? I don't think it's particularly useful....
-
- def tag(self):
- return self.inner.tag()
-
- def unroll(self):
- return self.inner.unroll()
-
- def isDistinguishableFrom(self, other):
- return self.inner.isDistinguishableFrom(other)
-
- def _getDependentObjects(self):
- return self.inner._getDependentObjects()
-
-class IDLWrapperType(IDLType):
- def __init__(self, location, inner, promiseInnerType=None):
- IDLType.__init__(self, location, inner.identifier.name)
- self.inner = inner
- self._identifier = inner.identifier
- self.builtin = False
- assert not promiseInnerType or inner.identifier.name == "Promise"
- self._promiseInnerType = promiseInnerType
-
- def __eq__(self, other):
- return isinstance(other, IDLWrapperType) and \
- self._identifier == other._identifier and \
- self.builtin == other.builtin
-
- def __str__(self):
- return str(self.name) + " (Wrapper)"
-
- def nullable(self):
- return False
-
- def isPrimitive(self):
- return False
-
- def isString(self):
- return False
-
- def isByteString(self):
- return False
-
- def isDOMString(self):
- return False
-
- def isScalarValueString(self):
- return False
-
- def isVoid(self):
- return False
-
- def isSequence(self):
- return False
-
- def isArray(self):
- return False
-
- def isDictionary(self):
- return isinstance(self.inner, IDLDictionary)
-
- def isInterface(self):
- return isinstance(self.inner, IDLInterface) or \
- isinstance(self.inner, IDLExternalInterface)
-
- def isCallbackInterface(self):
- return self.isInterface() and self.inner.isCallback()
-
- def isNonCallbackInterface(self):
- return self.isInterface() and not self.inner.isCallback()
-
- def isEnum(self):
- return isinstance(self.inner, IDLEnum)
-
- def isPromise(self):
- return isinstance(self.inner, IDLInterface) and \
- self.inner.identifier.name == "Promise"
-
- def isSerializable(self):
- if self.isInterface():
- if self.inner.isExternal():
- return False
- return any(m.isMethod() and m.isJsonifier() for m in self.inner.members)
- elif self.isEnum():
- return True
- elif self.isDictionary():
- return all(m.type.isSerializable() for m in self.inner.members)
- else:
- raise WebIDLError("IDLWrapperType wraps type %s that we don't know if "
- "is serializable" % type(self.inner), [self.location])
-
- def resolveType(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- self.inner.resolve(parentScope)
-
- def isComplete(self):
- return True
-
- def tag(self):
- if self.isInterface():
- return IDLType.Tags.interface
- elif self.isEnum():
- return IDLType.Tags.enum
- elif self.isDictionary():
- return IDLType.Tags.dictionary
- else:
- assert False
-
- def isDistinguishableFrom(self, other):
- if other.isUnion():
- # Just forward to the union; it'll deal
- return other.isDistinguishableFrom(self)
- assert self.isInterface() or self.isEnum() or self.isDictionary()
- if self.isEnum():
- return (other.isPrimitive() or other.isInterface() or other.isObject() or
- other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate())
- if self.isDictionary() and other.nullable():
- return False
- if other.isPrimitive() or other.isString() or other.isEnum() or other.isDate():
- return True
- if self.isDictionary():
- return other.isNonCallbackInterface()
-
- assert self.isInterface()
- if other.isInterface():
- if other.isSpiderMonkeyInterface():
- # Just let |other| handle things
- return other.isDistinguishableFrom(self)
- assert self.isGeckoInterface() and other.isGeckoInterface()
- if self.inner.isExternal() or other.unroll().inner.isExternal():
- return self != other
- return (len(self.inner.interfacesBasedOnSelf &
- other.unroll().inner.interfacesBasedOnSelf) == 0 and
- (self.isNonCallbackInterface() or
- other.isNonCallbackInterface()))
- if (other.isDictionary() or other.isCallback() or
- other.isSequence() or other.isMozMap() or other.isArray()):
- return self.isNonCallbackInterface()
-
- # Not much else |other| can be
- assert other.isObject()
- return False
-
- def isExposedInAllOf(self, exposureSet):
- if not self.isInterface():
- return True
- iface = self.inner
- if iface.isExternal():
- # Let's say true, though ideally we'd only do this when
- # exposureSet contains the primary global's name.
- return True
- if (iface.identifier.name == "Promise" and
- # Check the internal type
- not self._promiseInnerType.unroll().isExposedInAllOf(exposureSet)):
- return False
- return iface.exposureSet.issuperset(exposureSet)
-
- def _getDependentObjects(self):
- # NB: The codegen for an interface type depends on
- # a) That the identifier is in fact an interface (as opposed to
- # a dictionary or something else).
- # b) The native type of the interface.
- # If we depend on the interface object we will also depend on
- # anything the interface depends on which is undesirable. We
- # considered implementing a dependency just on the interface type
- # file, but then every modification to an interface would cause this
- # to be regenerated which is still undesirable. We decided not to
- # depend on anything, reasoning that:
- # 1) Changing the concrete type of the interface requires modifying
- # Bindings.conf, which is still a global dependency.
- # 2) Changing an interface to a dictionary (or vice versa) with the
- # same identifier should be incredibly rare.
- return set()
-
-class IDLBuiltinType(IDLType):
-
- Types = enum(
- # The integer types
- 'byte',
- 'octet',
- 'short',
- 'unsigned_short',
- 'long',
- 'unsigned_long',
- 'long_long',
- 'unsigned_long_long',
- # Additional primitive types
- 'boolean',
- 'unrestricted_float',
- 'float',
- 'unrestricted_double',
- # IMPORTANT: "double" must be the last primitive type listed
- 'double',
- # Other types
- 'any',
- 'domstring',
- 'bytestring',
- 'scalarvaluestring',
- 'object',
- 'date',
- 'void',
- # Funny stuff
- 'ArrayBuffer',
- 'ArrayBufferView',
- 'Int8Array',
- 'Uint8Array',
- 'Uint8ClampedArray',
- 'Int16Array',
- 'Uint16Array',
- 'Int32Array',
- 'Uint32Array',
- 'Float32Array',
- 'Float64Array'
- )
-
- TagLookup = {
- Types.byte: IDLType.Tags.int8,
- Types.octet: IDLType.Tags.uint8,
- Types.short: IDLType.Tags.int16,
- Types.unsigned_short: IDLType.Tags.uint16,
- Types.long: IDLType.Tags.int32,
- Types.unsigned_long: IDLType.Tags.uint32,
- Types.long_long: IDLType.Tags.int64,
- Types.unsigned_long_long: IDLType.Tags.uint64,
- Types.boolean: IDLType.Tags.bool,
- Types.unrestricted_float: IDLType.Tags.unrestricted_float,
- Types.float: IDLType.Tags.float,
- Types.unrestricted_double: IDLType.Tags.unrestricted_double,
- Types.double: IDLType.Tags.double,
- Types.any: IDLType.Tags.any,
- Types.domstring: IDLType.Tags.domstring,
- Types.bytestring: IDLType.Tags.bytestring,
- Types.scalarvaluestring: IDLType.Tags.scalarvaluestring,
- Types.object: IDLType.Tags.object,
- Types.date: IDLType.Tags.date,
- Types.void: IDLType.Tags.void,
- Types.ArrayBuffer: IDLType.Tags.interface,
- Types.ArrayBufferView: IDLType.Tags.interface,
- Types.Int8Array: IDLType.Tags.interface,
- Types.Uint8Array: IDLType.Tags.interface,
- Types.Uint8ClampedArray: IDLType.Tags.interface,
- Types.Int16Array: IDLType.Tags.interface,
- Types.Uint16Array: IDLType.Tags.interface,
- Types.Int32Array: IDLType.Tags.interface,
- Types.Uint32Array: IDLType.Tags.interface,
- Types.Float32Array: IDLType.Tags.interface,
- Types.Float64Array: IDLType.Tags.interface
- }
-
- def __init__(self, location, name, type):
- IDLType.__init__(self, location, name)
- self.builtin = True
- self._typeTag = type
-
- def isPrimitive(self):
- return self._typeTag <= IDLBuiltinType.Types.double
-
- def isBoolean(self):
- return self._typeTag == IDLBuiltinType.Types.boolean
-
- def isNumeric(self):
- return self.isPrimitive() and not self.isBoolean()
-
- def isString(self):
- return self._typeTag == IDLBuiltinType.Types.domstring or \
- self._typeTag == IDLBuiltinType.Types.bytestring or \
- self._typeTag == IDLBuiltinType.Types.scalarvaluestring
-
- def isByteString(self):
- return self._typeTag == IDLBuiltinType.Types.bytestring
-
- def isDOMString(self):
- return self._typeTag == IDLBuiltinType.Types.domstring
-
- def isScalarValueString(self):
- return self._typeTag == IDLBuiltinType.Types.scalarvaluestring
-
- def isInteger(self):
- return self._typeTag <= IDLBuiltinType.Types.unsigned_long_long
-
- def isArrayBuffer(self):
- return self._typeTag == IDLBuiltinType.Types.ArrayBuffer
-
- def isArrayBufferView(self):
- return self._typeTag == IDLBuiltinType.Types.ArrayBufferView
-
- def isTypedArray(self):
- return self._typeTag >= IDLBuiltinType.Types.Int8Array and \
- self._typeTag <= IDLBuiltinType.Types.Float64Array
-
- def isInterface(self):
- # TypedArray things are interface types per the TypedArray spec,
- # but we handle them as builtins because SpiderMonkey implements
- # all of it internally.
- return self.isArrayBuffer() or \
- self.isArrayBufferView() or \
- self.isTypedArray()
-
- def isNonCallbackInterface(self):
- # All the interfaces we can be are non-callback
- return self.isInterface()
-
- def isFloat(self):
- return self._typeTag == IDLBuiltinType.Types.float or \
- self._typeTag == IDLBuiltinType.Types.double or \
- self._typeTag == IDLBuiltinType.Types.unrestricted_float or \
- self._typeTag == IDLBuiltinType.Types.unrestricted_double
-
- def isUnrestricted(self):
- assert self.isFloat()
- return self._typeTag == IDLBuiltinType.Types.unrestricted_float or \
- self._typeTag == IDLBuiltinType.Types.unrestricted_double
-
- def isSerializable(self):
- return self.isPrimitive() or self.isDOMString() or self.isDate()
-
- def includesRestrictedFloat(self):
- return self.isFloat() and not self.isUnrestricted()
-
- def tag(self):
- return IDLBuiltinType.TagLookup[self._typeTag]
-
- def isDistinguishableFrom(self, other):
- if other.isUnion():
- # Just forward to the union; it'll deal
- return other.isDistinguishableFrom(self)
- if self.isBoolean():
- return (other.isNumeric() or other.isString() or other.isEnum() or
- other.isInterface() or other.isObject() or
- other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate())
- if self.isNumeric():
- return (other.isBoolean() or other.isString() or other.isEnum() or
- other.isInterface() or other.isObject() or
- other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate())
- if self.isString():
- return (other.isPrimitive() or other.isInterface() or
- other.isObject() or
- other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate())
- if self.isAny():
- # Can't tell "any" apart from anything
- return False
- if self.isObject():
- return other.isPrimitive() or other.isString() or other.isEnum()
- if self.isDate():
- return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isInterface() or other.isCallback() or
- other.isDictionary() or other.isSequence() or
- other.isMozMap() or other.isArray())
- if self.isVoid():
- return not other.isVoid()
- # Not much else we could be!
- assert self.isSpiderMonkeyInterface()
- # Like interfaces, but we know we're not a callback
- return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate() or
- (other.isInterface() and (
- # ArrayBuffer is distinguishable from everything
- # that's not an ArrayBuffer or a callback interface
- (self.isArrayBuffer() and not other.isArrayBuffer()) or
- # ArrayBufferView is distinguishable from everything
- # that's not an ArrayBufferView or typed array.
- (self.isArrayBufferView() and not other.isArrayBufferView() and
- not other.isTypedArray()) or
- # Typed arrays are distinguishable from everything
- # except ArrayBufferView and the same type of typed
- # array
- (self.isTypedArray() and not other.isArrayBufferView() and not
- (other.isTypedArray() and other.name == self.name)))))
-
- def _getDependentObjects(self):
- return set()
-
-BuiltinTypes = {
- IDLBuiltinType.Types.byte:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
- IDLBuiltinType.Types.byte),
- IDLBuiltinType.Types.octet:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Octet",
- IDLBuiltinType.Types.octet),
- IDLBuiltinType.Types.short:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Short",
- IDLBuiltinType.Types.short),
- IDLBuiltinType.Types.unsigned_short:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedShort",
- IDLBuiltinType.Types.unsigned_short),
- IDLBuiltinType.Types.long:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Long",
- IDLBuiltinType.Types.long),
- IDLBuiltinType.Types.unsigned_long:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedLong",
- IDLBuiltinType.Types.unsigned_long),
- IDLBuiltinType.Types.long_long:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "LongLong",
- IDLBuiltinType.Types.long_long),
- IDLBuiltinType.Types.unsigned_long_long:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedLongLong",
- IDLBuiltinType.Types.unsigned_long_long),
- IDLBuiltinType.Types.boolean:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Boolean",
- IDLBuiltinType.Types.boolean),
- IDLBuiltinType.Types.float:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float",
- IDLBuiltinType.Types.float),
- IDLBuiltinType.Types.unrestricted_float:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnrestrictedFloat",
- IDLBuiltinType.Types.unrestricted_float),
- IDLBuiltinType.Types.double:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Double",
- IDLBuiltinType.Types.double),
- IDLBuiltinType.Types.unrestricted_double:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnrestrictedDouble",
- IDLBuiltinType.Types.unrestricted_double),
- IDLBuiltinType.Types.any:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Any",
- IDLBuiltinType.Types.any),
- IDLBuiltinType.Types.domstring:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "String",
- IDLBuiltinType.Types.domstring),
- IDLBuiltinType.Types.bytestring:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "ByteString",
- IDLBuiltinType.Types.bytestring),
- IDLBuiltinType.Types.scalarvaluestring:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "ScalarValueString",
- IDLBuiltinType.Types.scalarvaluestring),
- IDLBuiltinType.Types.object:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object",
- IDLBuiltinType.Types.object),
- IDLBuiltinType.Types.date:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Date",
- IDLBuiltinType.Types.date),
- IDLBuiltinType.Types.void:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Void",
- IDLBuiltinType.Types.void),
- IDLBuiltinType.Types.ArrayBuffer:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBuffer",
- IDLBuiltinType.Types.ArrayBuffer),
- IDLBuiltinType.Types.ArrayBufferView:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBufferView",
- IDLBuiltinType.Types.ArrayBufferView),
- IDLBuiltinType.Types.Int8Array:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array",
- IDLBuiltinType.Types.Int8Array),
- IDLBuiltinType.Types.Uint8Array:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8Array",
- IDLBuiltinType.Types.Uint8Array),
- IDLBuiltinType.Types.Uint8ClampedArray:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8ClampedArray",
- IDLBuiltinType.Types.Uint8ClampedArray),
- IDLBuiltinType.Types.Int16Array:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int16Array",
- IDLBuiltinType.Types.Int16Array),
- IDLBuiltinType.Types.Uint16Array:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint16Array",
- IDLBuiltinType.Types.Uint16Array),
- IDLBuiltinType.Types.Int32Array:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int32Array",
- IDLBuiltinType.Types.Int32Array),
- IDLBuiltinType.Types.Uint32Array:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint32Array",
- IDLBuiltinType.Types.Uint32Array),
- IDLBuiltinType.Types.Float32Array:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float32Array",
- IDLBuiltinType.Types.Float32Array),
- IDLBuiltinType.Types.Float64Array:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array",
- IDLBuiltinType.Types.Float64Array)
- }
-
-
-integerTypeSizes = {
- IDLBuiltinType.Types.byte: (-128, 127),
- IDLBuiltinType.Types.octet: (0, 255),
- IDLBuiltinType.Types.short: (-32768, 32767),
- IDLBuiltinType.Types.unsigned_short: (0, 65535),
- IDLBuiltinType.Types.long: (-2147483648, 2147483647),
- IDLBuiltinType.Types.unsigned_long: (0, 4294967295),
- IDLBuiltinType.Types.long_long: (-9223372036854775808,
- 9223372036854775807),
- IDLBuiltinType.Types.unsigned_long_long: (0, 18446744073709551615)
- }
-
-def matchIntegerValueToType(value):
- for type, extremes in integerTypeSizes.items():
- (min, max) = extremes
- if value <= max and value >= min:
- return BuiltinTypes[type]
-
- return None
-
-class IDLValue(IDLObject):
- def __init__(self, location, type, value):
- IDLObject.__init__(self, location)
- self.type = type
- assert isinstance(type, IDLType)
-
- self.value = value
-
- def coerceToType(self, type, location):
- if type == self.type:
- return self # Nothing to do
-
- # We first check for unions to ensure that even if the union is nullable
- # we end up with the right flat member type, not the union's type.
- if type.isUnion():
- # We use the flat member types here, because if we have a nullable
- # member type, or a nested union, we want the type the value
- # actually coerces to, not the nullable or nested union type.
- for subtype in type.unroll().flatMemberTypes:
- try:
- coercedValue = self.coerceToType(subtype, location)
- # Create a new IDLValue to make sure that we have the
- # correct float/double type. This is necessary because we
- # use the value's type when it is a default value of a
- # union, and the union cares about the exact float type.
- return IDLValue(self.location, subtype, coercedValue.value)
- except:
- pass
- # If the type allows null, rerun this matching on the inner type, except
- # nullable enums. We handle those specially, because we want our
- # default string values to stay strings even when assigned to a nullable
- # enum.
- elif type.nullable() and not type.isEnum():
- innerValue = self.coerceToType(type.inner, location)
- return IDLValue(self.location, type, innerValue.value)
-
- elif self.type.isInteger() and type.isInteger():
- # We're both integer types. See if we fit.
-
- (min, max) = integerTypeSizes[type._typeTag]
- if self.value <= max and self.value >= min:
- # Promote
- return IDLValue(self.location, type, self.value)
- else:
- raise WebIDLError("Value %s is out of range for type %s." %
- (self.value, type), [location])
- elif self.type.isInteger() and type.isFloat():
- # Convert an integer literal into float
- if -2**24 <= self.value <= 2**24:
- floatType = BuiltinTypes[IDLBuiltinType.Types.float]
- return IDLValue(self.location, floatType, float(self.value))
- else:
- raise WebIDLError("Converting value %s to %s will lose precision." %
- (self.value, type), [location])
- elif self.type.isString() and type.isEnum():
- # Just keep our string, but make sure it's a valid value for this enum
- enum = type.unroll().inner
- if self.value not in enum.values():
- raise WebIDLError("'%s' is not a valid default value for enum %s"
- % (self.value, enum.identifier.name),
- [location, enum.location])
- return self
- elif self.type.isFloat() and type.isFloat():
- if (not type.isUnrestricted() and
- (self.value == float("inf") or self.value == float("-inf") or
- math.isnan(self.value))):
- raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted"
- % self.value, [location]);
- return self
- elif self.type.isString() and type.isScalarValueString():
- # Allow ScalarValueStrings to use default value just like
- # DOMString. No coercion is required in this case as Codegen.py
- # treats ScalarValueString just like DOMString, but with an
- # extra normalization step.
- assert self.type.isDOMString()
- return self
- raise WebIDLError("Cannot coerce type %s to type %s." %
- (self.type, type), [location])
-
- def _getDependentObjects(self):
- return set()
-
-class IDLNullValue(IDLObject):
- def __init__(self, location):
- IDLObject.__init__(self, location)
- self.type = None
- self.value = None
-
- def coerceToType(self, type, location):
- if (not isinstance(type, IDLNullableType) and
- not (type.isUnion() and type.hasNullableType) and
- not (type.isUnion() and type.hasDictionaryType) and
- not type.isDictionary() and
- not type.isAny()):
- raise WebIDLError("Cannot coerce null value to type %s." % type,
- [location])
-
- nullValue = IDLNullValue(self.location)
- if type.isUnion() and not type.nullable() and type.hasDictionaryType:
- # We're actually a default value for the union's dictionary member.
- # Use its type.
- for t in type.flatMemberTypes:
- if t.isDictionary():
- nullValue.type = t
- return nullValue
- nullValue.type = type
- return nullValue
-
- def _getDependentObjects(self):
- return set()
-
-class IDLEmptySequenceValue(IDLObject):
- def __init__(self, location):
- IDLObject.__init__(self, location)
- self.type = None
- self.value = None
-
- def coerceToType(self, type, location):
- if type.isUnion():
- # We use the flat member types here, because if we have a nullable
- # member type, or a nested union, we want the type the value
- # actually coerces to, not the nullable or nested union type.
- for subtype in type.unroll().flatMemberTypes:
- try:
- return self.coerceToType(subtype, location)
- except:
- pass
-
- if not type.isSequence():
- raise WebIDLError("Cannot coerce empty sequence value to type %s." % type,
- [location])
-
- emptySequenceValue = IDLEmptySequenceValue(self.location)
- emptySequenceValue.type = type
- return emptySequenceValue
-
- def _getDependentObjects(self):
- return set()
-
-class IDLUndefinedValue(IDLObject):
- def __init__(self, location):
- IDLObject.__init__(self, location)
- self.type = None
- self.value = None
-
- def coerceToType(self, type, location):
- if not type.isAny():
- raise WebIDLError("Cannot coerce undefined value to type %s." % type,
- [location])
-
- undefinedValue = IDLUndefinedValue(self.location)
- undefinedValue.type = type
- return undefinedValue
-
- def _getDependentObjects(self):
- return set()
-
-class IDLInterfaceMember(IDLObjectWithIdentifier):
-
- Tags = enum(
- 'Const',
- 'Attr',
- 'Method'
- )
-
- Special = enum(
- 'Static',
- 'Stringifier'
- )
-
- def __init__(self, location, identifier, tag):
- IDLObjectWithIdentifier.__init__(self, location, None, identifier)
- self.tag = tag
- self._extendedAttrDict = {}
- # _exposureGlobalNames are the global names listed in our [Exposed]
- # extended attribute. exposureSet is the exposure set as defined in the
- # Web IDL spec: it contains interface names.
- self._exposureGlobalNames = set()
- self.exposureSet = set()
-
- def isMethod(self):
- return self.tag == IDLInterfaceMember.Tags.Method
-
- def isAttr(self):
- return self.tag == IDLInterfaceMember.Tags.Attr
-
- def isConst(self):
- return self.tag == IDLInterfaceMember.Tags.Const
-
- def addExtendedAttributes(self, attrs):
- for attr in attrs:
- self.handleExtendedAttribute(attr)
- attrlist = attr.listValue()
- self._extendedAttrDict[attr.identifier()] = attrlist if len(attrlist) else True
-
- def handleExtendedAttribute(self, attr):
- pass
-
- def getExtendedAttribute(self, name):
- return self._extendedAttrDict.get(name, None)
-
- def finish(self, scope):
- for globalName in self._exposureGlobalNames:
- if globalName not in scope.globalNames:
- raise WebIDLError("Unknown [Exposed] value %s" % globalName,
- [self.location])
- globalNameSetToExposureSet(scope, self._exposureGlobalNames,
- self.exposureSet)
- self._scope = scope
-
- def validate(self):
- if (self.getExtendedAttribute("Pref") and
- self.exposureSet != set([self._scope.primaryGlobalName])):
- raise WebIDLError("[Pref] used on an interface member that is not "
- "%s-only" % self._scope.primaryGlobalName,
- [self.location])
-
-class IDLConst(IDLInterfaceMember):
- def __init__(self, location, identifier, type, value):
- IDLInterfaceMember.__init__(self, location, identifier,
- IDLInterfaceMember.Tags.Const)
-
- assert isinstance(type, IDLType)
- if type.isDictionary():
- raise WebIDLError("A constant cannot be of a dictionary type",
- [self.location])
- self.type = type
- self.value = value
-
- if identifier.name == "prototype":
- raise WebIDLError("The identifier of a constant must not be 'prototype'",
- [location])
-
- def __str__(self):
- return "'%s' const '%s'" % (self.type, self.identifier)
-
- def finish(self, scope):
- IDLInterfaceMember.finish(self, scope)
-
- if not self.type.isComplete():
- type = self.type.complete(scope)
- if not type.isPrimitive() and not type.isString():
- locations = [self.type.location, type.location]
- try:
- locations.append(type.inner.location)
- except:
- pass
- raise WebIDLError("Incorrect type for constant", locations)
- self.type = type
-
- # The value might not match the type
- coercedValue = self.value.coerceToType(self.type, self.location)
- assert coercedValue
-
- self.value = coercedValue
-
- def validate(self):
- IDLInterfaceMember.validate(self)
-
- def handleExtendedAttribute(self, attr):
- identifier = attr.identifier()
- if identifier == "Exposed":
- convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
- elif (identifier == "Pref" or
- identifier == "ChromeOnly" or
- identifier == "Func" or
- identifier == "AvailableIn" or
- identifier == "CheckPermissions"):
- # Known attributes that we don't need to do anything with here
- pass
- else:
- raise WebIDLError("Unknown extended attribute %s on constant" % identifier,
- [attr.location])
- IDLInterfaceMember.handleExtendedAttribute(self, attr)
-
- def _getDependentObjects(self):
- return set([self.type, self.value])
-
-class IDLAttribute(IDLInterfaceMember):
- def __init__(self, location, identifier, type, readonly, inherit=False,
- static=False, stringifier=False):
- IDLInterfaceMember.__init__(self, location, identifier,
- IDLInterfaceMember.Tags.Attr)
-
- assert isinstance(type, IDLType)
- self.type = type
- self.readonly = readonly
- self.inherit = inherit
- self.static = static
- self.lenientThis = False
- self._unforgeable = False
- self.stringifier = stringifier
- self.enforceRange = False
- self.clamp = False
- self.slotIndex = None
-
- if static and identifier.name == "prototype":
- raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
- [location])
-
- if readonly and inherit:
- raise WebIDLError("An attribute cannot be both 'readonly' and 'inherit'",
- [self.location])
-
- def isStatic(self):
- return self.static
-
- def __str__(self):
- return "'%s' attribute '%s'" % (self.type, self.identifier)
-
- def finish(self, scope):
- IDLInterfaceMember.finish(self, scope)
-
- if not self.type.isComplete():
- t = self.type.complete(scope)
-
- assert not isinstance(t, IDLUnresolvedType)
- assert not isinstance(t, IDLTypedefType)
- assert not isinstance(t.name, IDLUnresolvedIdentifier)
- self.type = t
-
- if self.type.isDictionary() and not self.getExtendedAttribute("Cached"):
- raise WebIDLError("An attribute cannot be of a dictionary type",
- [self.location])
- if self.type.isSequence() and not self.getExtendedAttribute("Cached"):
- raise WebIDLError("A non-cached attribute cannot be of a sequence "
- "type", [self.location])
- if self.type.isMozMap() and not self.getExtendedAttribute("Cached"):
- raise WebIDLError("A non-cached attribute cannot be of a MozMap "
- "type", [self.location])
- if self.type.isUnion():
- for f in self.type.unroll().flatMemberTypes:
- if f.isDictionary():
- raise WebIDLError("An attribute cannot be of a union "
- "type if one of its member types (or "
- "one of its member types's member "
- "types, and so on) is a dictionary "
- "type", [self.location, f.location])
- if f.isSequence():
- raise WebIDLError("An attribute cannot be of a union "
- "type if one of its member types (or "
- "one of its member types's member "
- "types, and so on) is a sequence "
- "type", [self.location, f.location])
- if f.isMozMap():
- raise WebIDLError("An attribute cannot be of a union "
- "type if one of its member types (or "
- "one of its member types's member "
- "types, and so on) is a MozMap "
- "type", [self.location, f.location])
- if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"):
- raise WebIDLError("An attribute with [PutForwards] must have an "
- "interface type as its type", [self.location])
-
- if not self.type.isInterface() and self.getExtendedAttribute("SameObject"):
- raise WebIDLError("An attribute with [SameObject] must have an "
- "interface type as its type", [self.location])
-
- def validate(self):
- IDLInterfaceMember.validate(self)
-
- if ((self.getExtendedAttribute("Cached") or
- self.getExtendedAttribute("StoreInSlot")) and
- not self.getExtendedAttribute("Constant") and
- not self.getExtendedAttribute("Pure")):
- raise WebIDLError("Cached attributes and attributes stored in "
- "slots must be constant or pure, since the "
- "getter won't always be called.",
- [self.location])
- if self.getExtendedAttribute("Frozen"):
- if (not self.type.isSequence() and not self.type.isDictionary() and
- not self.type.isMozMap()):
- raise WebIDLError("[Frozen] is only allowed on "
- "sequence-valued, dictionary-valued, and "
- "MozMap-valued attributes",
- [self.location])
- if not self.type.unroll().isExposedInAllOf(self.exposureSet):
- raise WebIDLError("Attribute returns a type that is not exposed "
- "everywhere where the attribute is exposed",
- [self.location])
-
- def handleExtendedAttribute(self, attr):
- identifier = attr.identifier()
- if identifier == "SetterThrows" and self.readonly:
- raise WebIDLError("Readonly attributes must not be flagged as "
- "[SetterThrows]",
- [self.location])
- elif (((identifier == "Throws" or identifier == "GetterThrows") and
- self.getExtendedAttribute("StoreInSlot")) or
- (identifier == "StoreInSlot" and
- (self.getExtendedAttribute("Throws") or
- self.getExtendedAttribute("GetterThrows")))):
- raise WebIDLError("Throwing things can't be [Pure] or [Constant] "
- "or [SameObject] or [StoreInSlot]",
- [attr.location])
- elif identifier == "LenientThis":
- if not attr.noArguments():
- raise WebIDLError("[LenientThis] must take no arguments",
- [attr.location])
- if self.isStatic():
- raise WebIDLError("[LenientThis] is only allowed on non-static "
- "attributes", [attr.location, self.location])
- if self.getExtendedAttribute("CrossOriginReadable"):
- raise WebIDLError("[LenientThis] is not allowed in combination "
- "with [CrossOriginReadable]",
- [attr.location, self.location])
- if self.getExtendedAttribute("CrossOriginWritable"):
- raise WebIDLError("[LenientThis] is not allowed in combination "
- "with [CrossOriginWritable]",
- [attr.location, self.location])
- self.lenientThis = True
- elif identifier == "Unforgeable":
- if self.isStatic():
- raise WebIDLError("[Unforgeable] is only allowed on non-static "
- "attributes", [attr.location, self.location])
- self._unforgeable = True
- elif identifier == "SameObject" and not self.readonly:
- raise WebIDLError("[SameObject] only allowed on readonly attributes",
- [attr.location, self.location])
- elif identifier == "Constant" and not self.readonly:
- raise WebIDLError("[Constant] only allowed on readonly attributes",
- [attr.location, self.location])
- elif identifier == "PutForwards":
- if not self.readonly:
- raise WebIDLError("[PutForwards] is only allowed on readonly "
- "attributes", [attr.location, self.location])
- if self.isStatic():
- raise WebIDLError("[PutForwards] is only allowed on non-static "
- "attributes", [attr.location, self.location])
- if self.getExtendedAttribute("Replaceable") is not None:
- raise WebIDLError("[PutForwards] and [Replaceable] can't both "
- "appear on the same attribute",
- [attr.location, self.location])
- if not attr.hasValue():
- raise WebIDLError("[PutForwards] takes an identifier",
- [attr.location, self.location])
- elif identifier == "Replaceable":
- if self.getExtendedAttribute("PutForwards") is not None:
- raise WebIDLError("[PutForwards] and [Replaceable] can't both "
- "appear on the same attribute",
- [attr.location, self.location])
- elif identifier == "LenientFloat":
- if self.readonly:
- raise WebIDLError("[LenientFloat] used on a readonly attribute",
- [attr.location, self.location])
- if not self.type.includesRestrictedFloat():
- raise WebIDLError("[LenientFloat] used on an attribute with a "
- "non-restricted-float type",
- [attr.location, self.location])
- elif identifier == "EnforceRange":
- if self.readonly:
- raise WebIDLError("[EnforceRange] used on a readonly attribute",
- [attr.location, self.location])
- self.enforceRange = True
- elif identifier == "Clamp":
- if self.readonly:
- raise WebIDLError("[Clamp] used on a readonly attribute",
- [attr.location, self.location])
- self.clamp = True
- elif identifier == "StoreInSlot":
- if self.getExtendedAttribute("Cached"):
- raise WebIDLError("[StoreInSlot] and [Cached] must not be "
- "specified on the same attribute",
- [attr.location, self.location])
- elif identifier == "Cached":
- if self.getExtendedAttribute("StoreInSlot"):
- raise WebIDLError("[Cached] and [StoreInSlot] must not be "
- "specified on the same attribute",
- [attr.location, self.location])
- elif (identifier == "CrossOriginReadable" or
- identifier == "CrossOriginWritable"):
- if not attr.noArguments() and identifier == "CrossOriginReadable":
- raise WebIDLError("[%s] must take no arguments" % identifier,
- [attr.location])
- if self.isStatic():
- raise WebIDLError("[%s] is only allowed on non-static "
- "attributes" % identifier,
- [attr.location, self.location])
- if self.getExtendedAttribute("LenientThis"):
- raise WebIDLError("[LenientThis] is not allowed in combination "
- "with [%s]" % identifier,
- [attr.location, self.location])
- elif identifier == "Exposed":
- convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
- elif (identifier == "Pref" or
- identifier == "SetterThrows" or
- identifier == "Pure" or
- identifier == "Throws" or
- identifier == "GetterThrows" or
- identifier == "ChromeOnly" or
- identifier == "SameObject" or
- identifier == "Constant" or
- identifier == "Func" or
- identifier == "Frozen" or
- identifier == "AvailableIn" or
- identifier == "NewObject" or
- identifier == "CheckPermissions"):
- # Known attributes that we don't need to do anything with here
- pass
- else:
- raise WebIDLError("Unknown extended attribute %s on attribute" % identifier,
- [attr.location])
- IDLInterfaceMember.handleExtendedAttribute(self, attr)
-
- def resolve(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- self.type.resolveType(parentScope)
- IDLObjectWithIdentifier.resolve(self, parentScope)
-
- def addExtendedAttributes(self, attrs):
- attrs = self.checkForStringHandlingExtendedAttributes(attrs)
- IDLInterfaceMember.addExtendedAttributes(self, attrs)
-
- def hasLenientThis(self):
- return self.lenientThis
-
- def isUnforgeable(self):
- return self._unforgeable
-
- def _getDependentObjects(self):
- return set([self.type])
-
-class IDLArgument(IDLObjectWithIdentifier):
- def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False):
- IDLObjectWithIdentifier.__init__(self, location, None, identifier)
-
- assert isinstance(type, IDLType)
- self.type = type
-
- self.optional = optional
- self.defaultValue = defaultValue
- self.variadic = variadic
- self.dictionaryMember = dictionaryMember
- self._isComplete = False
- self.enforceRange = False
- self.clamp = False
- self._allowTreatNonCallableAsNull = False
-
- assert not variadic or optional
-
- def addExtendedAttributes(self, attrs):
- attrs = self.checkForStringHandlingExtendedAttributes(
- attrs,
- isDictionaryMember=self.dictionaryMember,
- isOptional=self.optional)
- for attribute in attrs:
- identifier = attribute.identifier()
- if identifier == "Clamp":
- if not attribute.noArguments():
- raise WebIDLError("[Clamp] must take no arguments",
- [attribute.location])
- if self.enforceRange:
- raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
- [self.location]);
- self.clamp = True
- elif identifier == "EnforceRange":
- if not attribute.noArguments():
- raise WebIDLError("[EnforceRange] must take no arguments",
- [attribute.location])
- if self.clamp:
- raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
- [self.location]);
- self.enforceRange = True
- elif identifier == "TreatNonCallableAsNull":
- self._allowTreatNonCallableAsNull = True
- else:
- raise WebIDLError("Unhandled extended attribute on an argument",
- [attribute.location])
-
- def isComplete(self):
- return self._isComplete
-
- def complete(self, scope):
- if self._isComplete:
- return
-
- self._isComplete = True
-
- if not self.type.isComplete():
- type = self.type.complete(scope)
- assert not isinstance(type, IDLUnresolvedType)
- assert not isinstance(type, IDLTypedefType)
- assert not isinstance(type.name, IDLUnresolvedIdentifier)
- self.type = type
-
- if ((self.type.isDictionary() or
- self.type.isUnion() and self.type.unroll().hasDictionaryType) and
- self.optional and not self.defaultValue):
- # Default optional dictionaries to null, for simplicity,
- # so the codegen doesn't have to special-case this.
- self.defaultValue = IDLNullValue(self.location)
- elif self.type.isAny():
- assert (self.defaultValue is None or
- isinstance(self.defaultValue, IDLNullValue))
- # optional 'any' values always have a default value
- if self.optional and not self.defaultValue and not self.variadic:
- # Set the default value to undefined, for simplicity, so the
- # codegen doesn't have to special-case this.
- self.defaultValue = IDLUndefinedValue(self.location)
-
- # Now do the coercing thing; this needs to happen after the
- # above creation of a default value.
- if self.defaultValue:
- self.defaultValue = self.defaultValue.coerceToType(self.type,
- self.location)
- assert self.defaultValue
-
- def allowTreatNonCallableAsNull(self):
- return self._allowTreatNonCallableAsNull
-
- def _getDependentObjects(self):
- deps = set([self.type])
- if self.defaultValue:
- deps.add(self.defaultValue)
- return deps
-
-class IDLCallbackType(IDLType, IDLObjectWithScope):
- def __init__(self, location, parentScope, identifier, returnType, arguments):
- assert isinstance(returnType, IDLType)
-
- IDLType.__init__(self, location, identifier.name)
-
- self._returnType = returnType
- # Clone the list
- self._arguments = list(arguments)
-
- IDLObjectWithScope.__init__(self, location, parentScope, identifier)
-
- for (returnType, arguments) in self.signatures():
- for argument in arguments:
- argument.resolve(self)
-
- self._treatNonCallableAsNull = False
- self._treatNonObjectAsNull = False
-
- def module(self):
- return self.location.filename().split('/')[-1].split('.webidl')[0] + 'Binding'
-
- def isCallback(self):
- return True
-
- def signatures(self):
- return [(self._returnType, self._arguments)]
-
- def tag(self):
- return IDLType.Tags.callback
-
- def finish(self, scope):
- if not self._returnType.isComplete():
- type = self._returnType.complete(scope)
-
- assert not isinstance(type, IDLUnresolvedType)
- assert not isinstance(type, IDLTypedefType)
- assert not isinstance(type.name, IDLUnresolvedIdentifier)
- self._returnType = type
-
- for argument in self._arguments:
- if argument.type.isComplete():
- continue
-
- type = argument.type.complete(scope)
-
- assert not isinstance(type, IDLUnresolvedType)
- assert not isinstance(type, IDLTypedefType)
- assert not isinstance(type.name, IDLUnresolvedIdentifier)
- argument.type = type
-
- def validate(self):
- pass
-
- def isDistinguishableFrom(self, other):
- if other.isUnion():
- # Just forward to the union; it'll deal
- return other.isDistinguishableFrom(self)
- return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isNonCallbackInterface() or other.isDate())
-
- def addExtendedAttributes(self, attrs):
- unhandledAttrs = []
- for attr in attrs:
- if attr.identifier() == "TreatNonCallableAsNull":
- self._treatNonCallableAsNull = True
- elif attr.identifier() == "TreatNonObjectAsNull":
- self._treatNonObjectAsNull = True
- else:
- unhandledAttrs.append(attr)
- if self._treatNonCallableAsNull and self._treatNonObjectAsNull:
- raise WebIDLError("Cannot specify both [TreatNonCallableAsNull] "
- "and [TreatNonObjectAsNull]", [self.location])
- if len(unhandledAttrs) != 0:
- IDLType.addExtendedAttributes(self, unhandledAttrs)
-
- def _getDependentObjects(self):
- return set([self._returnType] + self._arguments)
-
-class IDLMethodOverload:
- """
- A class that represents a single overload of a WebIDL method. This is not
- quite the same as an element of the "effective overload set" in the spec,
- because separate IDLMethodOverloads are not created based on arguments being
- optional. Rather, when multiple methods have the same name, there is an
- IDLMethodOverload for each one, all hanging off an IDLMethod representing
- the full set of overloads.
- """
- def __init__(self, returnType, arguments, location):
- self.returnType = returnType
- # Clone the list of arguments, just in case
- self.arguments = list(arguments)
- self.location = location
-
- def _getDependentObjects(self):
- deps = set(self.arguments)
- deps.add(self.returnType)
- return deps
-
-class IDLMethod(IDLInterfaceMember, IDLScope):
-
- Special = enum(
- 'Getter',
- 'Setter',
- 'Creator',
- 'Deleter',
- 'LegacyCaller',
- base=IDLInterfaceMember.Special
- )
-
- TypeSuffixModifier = enum(
- 'None',
- 'QMark',
- 'Brackets'
- )
-
- NamedOrIndexed = enum(
- 'Neither',
- 'Named',
- 'Indexed'
- )
-
- def __init__(self, location, identifier, returnType, arguments,
- static=False, getter=False, setter=False, creator=False,
- deleter=False, specialType=NamedOrIndexed.Neither,
- legacycaller=False, stringifier=False, jsonifier=False):
- # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
- IDLInterfaceMember.__init__(self, location, identifier,
- IDLInterfaceMember.Tags.Method)
-
- self._hasOverloads = False
-
- assert isinstance(returnType, IDLType)
-
- # self._overloads is a list of IDLMethodOverloads
- self._overloads = [IDLMethodOverload(returnType, arguments, location)]
-
- assert isinstance(static, bool)
- self._static = static
- assert isinstance(getter, bool)
- self._getter = getter
- assert isinstance(setter, bool)
- self._setter = setter
- assert isinstance(creator, bool)
- self._creator = creator
- assert isinstance(deleter, bool)
- self._deleter = deleter
- assert isinstance(legacycaller, bool)
- self._legacycaller = legacycaller
- assert isinstance(stringifier, bool)
- self._stringifier = stringifier
- assert isinstance(jsonifier, bool)
- self._jsonifier = jsonifier
- self._specialType = specialType
- self._unforgeable = False
-
- if static and identifier.name == "prototype":
- raise WebIDLError("The identifier of a static operation must not be 'prototype'",
- [location])
-
- self.assertSignatureConstraints()
-
- def __str__(self):
- return "Method '%s'" % self.identifier
-
- def assertSignatureConstraints(self):
- if self._getter or self._deleter:
- assert len(self._overloads) == 1
- overload = self._overloads[0]
- arguments = overload.arguments
- assert len(arguments) == 1
- assert arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or \
- arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]
- assert not arguments[0].optional and not arguments[0].variadic
- assert not self._getter or not overload.returnType.isVoid()
-
- if self._setter or self._creator:
- assert len(self._overloads) == 1
- arguments = self._overloads[0].arguments
- assert len(arguments) == 2
- assert arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or \
- arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]
- assert not arguments[0].optional and not arguments[0].variadic
- assert not arguments[1].optional and not arguments[1].variadic
-
- if self._stringifier:
- assert len(self._overloads) == 1
- overload = self._overloads[0]
- assert len(overload.arguments) == 0
- assert overload.returnType == BuiltinTypes[IDLBuiltinType.Types.domstring]
-
- if self._jsonifier:
- assert len(self._overloads) == 1
- overload = self._overloads[0]
- assert len(overload.arguments) == 0
- assert overload.returnType == BuiltinTypes[IDLBuiltinType.Types.object]
-
- def isStatic(self):
- return self._static
-
- def isGetter(self):
- return self._getter
-
- def isSetter(self):
- return self._setter
-
- def isCreator(self):
- return self._creator
-
- def isDeleter(self):
- return self._deleter
-
- def isNamed(self):
- assert self._specialType == IDLMethod.NamedOrIndexed.Named or \
- self._specialType == IDLMethod.NamedOrIndexed.Indexed
- return self._specialType == IDLMethod.NamedOrIndexed.Named
-
- def isIndexed(self):
- assert self._specialType == IDLMethod.NamedOrIndexed.Named or \
- self._specialType == IDLMethod.NamedOrIndexed.Indexed
- return self._specialType == IDLMethod.NamedOrIndexed.Indexed
-
- def isLegacycaller(self):
- return self._legacycaller
-
- def isStringifier(self):
- return self._stringifier
-
- def isJsonifier(self):
- return self._jsonifier
-
- def hasOverloads(self):
- return self._hasOverloads
-
- def isIdentifierLess(self):
- return self.identifier.name[:2] == "__" and self.identifier.name != "__noSuchMethod__"
-
- def resolve(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- IDLObjectWithIdentifier.resolve(self, parentScope)
- IDLScope.__init__(self, self.location, parentScope, self.identifier)
- for (returnType, arguments) in self.signatures():
- for argument in arguments:
- argument.resolve(self)
-
- def addOverload(self, method):
- assert len(method._overloads) == 1
-
- if self._extendedAttrDict != method ._extendedAttrDict:
- raise WebIDLError("Extended attributes differ on different "
- "overloads of %s" % method.identifier,
- [self.location, method.location])
-
- self._overloads.extend(method._overloads)
-
- self._hasOverloads = True
-
- if self.isStatic() != method.isStatic():
- raise WebIDLError("Overloaded identifier %s appears with different values of the 'static' attribute" % method.identifier,
- [method.location])
-
- if self.isLegacycaller() != method.isLegacycaller():
- raise WebIDLError("Overloaded identifier %s appears with different values of the 'legacycaller' attribute" % method.identifier,
- [method.location])
-
- # Can't overload special things!
- assert not self.isGetter()
- assert not method.isGetter()
- assert not self.isSetter()
- assert not method.isSetter()
- assert not self.isCreator()
- assert not method.isCreator()
- assert not self.isDeleter()
- assert not method.isDeleter()
- assert not self.isStringifier()
- assert not method.isStringifier()
- assert not self.isJsonifier()
- assert not method.isJsonifier()
-
- return self
-
- def signatures(self):
- return [(overload.returnType, overload.arguments) for overload in
- self._overloads]
-
- def finish(self, scope):
- IDLInterfaceMember.finish(self, scope)
-
- overloadWithPromiseReturnType = None
- overloadWithoutPromiseReturnType = None
- for overload in self._overloads:
- variadicArgument = None
-
- arguments = overload.arguments
- for (idx, argument) in enumerate(arguments):
- if not argument.isComplete():
- argument.complete(scope)
- assert argument.type.isComplete()
-
- if (argument.type.isDictionary() or
- (argument.type.isUnion() and
- argument.type.unroll().hasDictionaryType)):
- # Dictionaries and unions containing dictionaries at the
- # end of the list or followed by optional arguments must be
- # optional.
- if (not argument.optional and
- all(arg.optional for arg in arguments[idx+1:])):
- raise WebIDLError("Dictionary argument or union "
- "argument containing a dictionary "
- "not followed by a required argument "
- "must be optional",
- [argument.location])
-
- # An argument cannot be a Nullable Dictionary
- if argument.type.nullable():
- raise WebIDLError("An argument cannot be a nullable "
- "dictionary or nullable union "
- "containing a dictionary",
- [argument.location])
-
- # Only the last argument can be variadic
- if variadicArgument:
- raise WebIDLError("Variadic argument is not last argument",
- [variadicArgument.location])
- if argument.variadic:
- variadicArgument = argument
-
- returnType = overload.returnType
- if not returnType.isComplete():
- returnType = returnType.complete(scope)
- assert not isinstance(returnType, IDLUnresolvedType)
- assert not isinstance(returnType, IDLTypedefType)
- assert not isinstance(returnType.name, IDLUnresolvedIdentifier)
- overload.returnType = returnType
-
- if returnType.isPromise():
- overloadWithPromiseReturnType = overload
- else:
- overloadWithoutPromiseReturnType = overload
-
- # Make sure either all our overloads return Promises or none do
- if overloadWithPromiseReturnType and overloadWithoutPromiseReturnType:
- raise WebIDLError("We have overloads with both Promise and "
- "non-Promise return types",
- [overloadWithPromiseReturnType.location,
- overloadWithoutPromiseReturnType.location])
-
- if overloadWithPromiseReturnType and self._legacycaller:
- raise WebIDLError("May not have a Promise return type for a "
- "legacycaller.",
- [overloadWithPromiseReturnType.location])
-
- # Now compute various information that will be used by the
- # WebIDL overload resolution algorithm.
- self.maxArgCount = max(len(s[1]) for s in self.signatures())
- self.allowedArgCounts = [ i for i in range(self.maxArgCount+1)
- if len(self.signaturesForArgCount(i)) != 0 ]
-
- def validate(self):
- IDLInterfaceMember.validate(self)
-
- # Make sure our overloads are properly distinguishable and don't have
- # different argument types before the distinguishing args.
- for argCount in self.allowedArgCounts:
- possibleOverloads = self.overloadsForArgCount(argCount)
- if len(possibleOverloads) == 1:
- continue
- distinguishingIndex = self.distinguishingIndexForArgCount(argCount)
- for idx in range(distinguishingIndex):
- firstSigType = possibleOverloads[0].arguments[idx].type
- for overload in possibleOverloads[1:]:
- if overload.arguments[idx].type != firstSigType:
- raise WebIDLError(
- "Signatures for method '%s' with %d arguments have "
- "different types of arguments at index %d, which "
- "is before distinguishing index %d" %
- (self.identifier.name, argCount, idx,
- distinguishingIndex),
- [self.location, overload.location])
-
- for overload in self._overloads:
- if not overload.returnType.unroll().isExposedInAllOf(self.exposureSet):
- raise WebIDLError("Overload returns a type that is not exposed "
- "everywhere where the method is exposed",
- [overload.location])
-
- def overloadsForArgCount(self, argc):
- return [overload for overload in self._overloads if
- len(overload.arguments) == argc or
- (len(overload.arguments) > argc and
- all(arg.optional for arg in overload.arguments[argc:])) or
- (len(overload.arguments) < argc and
- len(overload.arguments) > 0 and
- overload.arguments[-1].variadic)]
-
- def signaturesForArgCount(self, argc):
- return [(overload.returnType, overload.arguments) for overload
- in self.overloadsForArgCount(argc)]
-
- def locationsForArgCount(self, argc):
- return [overload.location for overload in self.overloadsForArgCount(argc)]
-
- def distinguishingIndexForArgCount(self, argc):
- def isValidDistinguishingIndex(idx, signatures):
- for (firstSigIndex, (firstRetval, firstArgs)) in enumerate(signatures[:-1]):
- for (secondRetval, secondArgs) in signatures[firstSigIndex+1:]:
- if idx < len(firstArgs):
- firstType = firstArgs[idx].type
- else:
- assert(firstArgs[-1].variadic)
- firstType = firstArgs[-1].type
- if idx < len(secondArgs):
- secondType = secondArgs[idx].type
- else:
- assert(secondArgs[-1].variadic)
- secondType = secondArgs[-1].type
- if not firstType.isDistinguishableFrom(secondType):
- return False
- return True
- signatures = self.signaturesForArgCount(argc)
- for idx in range(argc):
- if isValidDistinguishingIndex(idx, signatures):
- return idx
- # No valid distinguishing index. Time to throw
- locations = self.locationsForArgCount(argc)
- raise WebIDLError("Signatures with %d arguments for method '%s' are not "
- "distinguishable" % (argc, self.identifier.name),
- locations)
-
- def handleExtendedAttribute(self, attr):
- identifier = attr.identifier()
- if identifier == "GetterThrows":
- raise WebIDLError("Methods must not be flagged as "
- "[GetterThrows]",
- [attr.location, self.location])
- elif identifier == "SetterThrows":
- raise WebIDLError("Methods must not be flagged as "
- "[SetterThrows]",
- [attr.location, self.location])
- elif identifier == "Unforgeable":
- if self.isStatic():
- raise WebIDLError("[Unforgeable] is only allowed on non-static "
- "methods", [attr.location, self.location])
- self._unforgeable = True
- elif identifier == "SameObject":
- raise WebIDLError("Methods must not be flagged as [SameObject]",
- [attr.location, self.location]);
- elif identifier == "Constant":
- raise WebIDLError("Methods must not be flagged as [Constant]",
- [attr.location, self.location]);
- elif identifier == "PutForwards":
- raise WebIDLError("Only attributes support [PutForwards]",
- [attr.location, self.location])
- elif identifier == "LenientFloat":
- # This is called before we've done overload resolution
- assert len(self.signatures()) == 1
- sig = self.signatures()[0]
- if not sig[0].isVoid():
- raise WebIDLError("[LenientFloat] used on a non-void method",
- [attr.location, self.location])
- if not any(arg.type.includesRestrictedFloat() for arg in sig[1]):
- raise WebIDLError("[LenientFloat] used on an operation with no "
- "restricted float type arguments",
- [attr.location, self.location])
- elif identifier == "Exposed":
- convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
- elif (identifier == "Pure" or
- identifier == "CrossOriginCallable" or
- identifier == "WebGLHandlesContextLoss"):
- # Known no-argument attributes.
- if not attr.noArguments():
- raise WebIDLError("[%s] must take no arguments" % identifier,
- [attr.location])
- elif (identifier == "Throws" or
- identifier == "NewObject" or
- identifier == "ChromeOnly" or
- identifier == "Pref" or
- identifier == "Func" or
- identifier == "AvailableIn" or
- identifier == "CheckPermissions"):
- # Known attributes that we don't need to do anything with here
- pass
- else:
- raise WebIDLError("Unknown extended attribute %s on method" % identifier,
- [attr.location])
- IDLInterfaceMember.handleExtendedAttribute(self, attr)
-
- def returnsPromise(self):
- return self._overloads[0].returnType.isPromise()
-
- def isUnforgeable(self):
- return self._unforgeable
-
- def _getDependentObjects(self):
- deps = set()
- for overload in self._overloads:
- deps.union(overload._getDependentObjects())
- return deps
-
-class IDLImplementsStatement(IDLObject):
- def __init__(self, location, implementor, implementee):
- IDLObject.__init__(self, location)
- self.implementor = implementor;
- self.implementee = implementee
-
- def finish(self, scope):
- assert(isinstance(self.implementor, IDLIdentifierPlaceholder))
- assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
- implementor = self.implementor.finish(scope)
- implementee = self.implementee.finish(scope)
- # NOTE: we depend on not setting self.implementor and
- # self.implementee here to keep track of the original
- # locations.
- if not isinstance(implementor, IDLInterface):
- raise WebIDLError("Left-hand side of 'implements' is not an "
- "interface",
- [self.implementor.location])
- if implementor.isCallback():
- raise WebIDLError("Left-hand side of 'implements' is a callback "
- "interface",
- [self.implementor.location])
- if not isinstance(implementee, IDLInterface):
- raise WebIDLError("Right-hand side of 'implements' is not an "
- "interface",
- [self.implementee.location])
- if implementee.isCallback():
- raise WebIDLError("Right-hand side of 'implements' is a callback "
- "interface",
- [self.implementee.location])
- implementor.addImplementedInterface(implementee)
-
- def validate(self):
- pass
-
- def addExtendedAttributes(self, attrs):
- assert len(attrs) == 0
-
-class IDLExtendedAttribute(IDLObject):
- """
- A class to represent IDL extended attributes so we can give them locations
- """
- def __init__(self, location, tuple):
- IDLObject.__init__(self, location)
- self._tuple = tuple
-
- def identifier(self):
- return self._tuple[0]
-
- def noArguments(self):
- return len(self._tuple) == 1
-
- def hasValue(self):
- return len(self._tuple) >= 2 and isinstance(self._tuple[1], str)
-
- def value(self):
- assert(self.hasValue())
- return self._tuple[1]
-
- def hasArgs(self):
- return (len(self._tuple) == 2 and isinstance(self._tuple[1], list) or
- len(self._tuple) == 3)
-
- def args(self):
- assert(self.hasArgs())
- # Our args are our last element
- return self._tuple[-1]
-
- def listValue(self):
- """
- Backdoor for storing random data in _extendedAttrDict
- """
- return list(self._tuple)[1:]
-
-# Parser
-
-class Tokenizer(object):
- tokens = [
- "INTEGER",
- "FLOATLITERAL",
- "IDENTIFIER",
- "STRING",
- "WHITESPACE",
- "OTHER"
- ]
-
- def t_FLOATLITERAL(self, t):
- r'(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+|Infinity))|NaN'
- t.value = float(t.value)
- return t
-
- def t_INTEGER(self, t):
- r'-?(0([0-7]+|[Xx][0-9A-Fa-f]+)?|[1-9][0-9]*)'
- try:
- # Can't use int(), because that doesn't handle octal properly.
- t.value = parseInt(t.value)
- except:
- raise WebIDLError("Invalid integer literal",
- [Location(lexer=self.lexer,
- lineno=self.lexer.lineno,
- lexpos=self.lexer.lexpos,
- filename=self._filename)])
- return t
-
- def t_IDENTIFIER(self, t):
- r'[A-Z_a-z][0-9A-Z_a-z-]*'
- t.type = self.keywords.get(t.value, 'IDENTIFIER')
- return t
-
- def t_STRING(self, t):
- r'"[^"]*"'
- t.value = t.value[1:-1]
- return t
-
- def t_WHITESPACE(self, t):
- r'[\t\n\r ]+|[\t\n\r ]*((//[^\n]*|/\*.*?\*/)[\t\n\r ]*)+'
- pass
-
- def t_ELLIPSIS(self, t):
- r'\.\.\.'
- t.type = self.keywords.get(t.value)
- return t
-
- def t_OTHER(self, t):
- r'[^\t\n\r 0-9A-Z_a-z]'
- t.type = self.keywords.get(t.value, 'OTHER')
- return t
-
- keywords = {
- "module": "MODULE",
- "interface": "INTERFACE",
- "partial": "PARTIAL",
- "dictionary": "DICTIONARY",
- "exception": "EXCEPTION",
- "enum": "ENUM",
- "callback": "CALLBACK",
- "typedef": "TYPEDEF",
- "implements": "IMPLEMENTS",
- "const": "CONST",
- "null": "NULL",
- "true": "TRUE",
- "false": "FALSE",
- "serializer": "SERIALIZER",
- "stringifier": "STRINGIFIER",
- "jsonifier": "JSONIFIER",
- "unrestricted": "UNRESTRICTED",
- "attribute": "ATTRIBUTE",
- "readonly": "READONLY",
- "inherit": "INHERIT",
- "static": "STATIC",
- "getter": "GETTER",
- "setter": "SETTER",
- "creator": "CREATOR",
- "deleter": "DELETER",
- "legacycaller": "LEGACYCALLER",
- "optional": "OPTIONAL",
- "...": "ELLIPSIS",
- "::": "SCOPE",
- "Date": "DATE",
- "DOMString": "DOMSTRING",
- "ByteString": "BYTESTRING",
- "ScalarValueString": "SCALARVALUESTRING",
- "any": "ANY",
- "boolean": "BOOLEAN",
- "byte": "BYTE",
- "double": "DOUBLE",
- "float": "FLOAT",
- "long": "LONG",
- "object": "OBJECT",
- "octet": "OCTET",
- "optional": "OPTIONAL",
- "Promise": "PROMISE",
- "sequence": "SEQUENCE",
- "MozMap": "MOZMAP",
- "short": "SHORT",
- "unsigned": "UNSIGNED",
- "void": "VOID",
- ":": "COLON",
- ";": "SEMICOLON",
- "{": "LBRACE",
- "}": "RBRACE",
- "(": "LPAREN",
- ")": "RPAREN",
- "[": "LBRACKET",
- "]": "RBRACKET",
- "?": "QUESTIONMARK",
- ",": "COMMA",
- "=": "EQUALS",
- "<": "LT",
- ">": "GT",
- "ArrayBuffer": "ARRAYBUFFER",
- "or": "OR"
- }
-
- tokens.extend(keywords.values())
-
- def t_error(self, t):
- raise WebIDLError("Unrecognized Input",
- [Location(lexer=self.lexer,
- lineno=self.lexer.lineno,
- lexpos=self.lexer.lexpos,
- filename = self.filename)])
-
- def __init__(self, outputdir, lexer=None):
- if lexer:
- self.lexer = lexer
- else:
- self.lexer = lex.lex(object=self,
- outputdir=outputdir,
- lextab='webidllex',
- reflags=re.DOTALL)
-
-class SqueakyCleanLogger(object):
- errorWhitelist = [
- # Web IDL defines the WHITESPACE token, but doesn't actually
- # use it ... so far.
- "Token 'WHITESPACE' defined, but not used",
- # And that means we have an unused token
- "There is 1 unused token",
- # Web IDL defines a OtherOrComma rule that's only used in
- # ExtendedAttributeInner, which we don't use yet.
- "Rule 'OtherOrComma' defined, but not used",
- # And an unused rule
- "There is 1 unused rule",
- # And the OtherOrComma grammar symbol is unreachable.
- "Symbol 'OtherOrComma' is unreachable",
- # Which means the Other symbol is unreachable.
- "Symbol 'Other' is unreachable",
- ]
- def __init__(self):
- self.errors = []
- def debug(self, msg, *args, **kwargs):
- pass
- info = debug
- def warning(self, msg, *args, **kwargs):
- if msg == "%s:%d: Rule '%s' defined, but not used":
- # Munge things so we don't have to hardcode filenames and
- # line numbers in our whitelist.
- whitelistmsg = "Rule '%s' defined, but not used"
- whitelistargs = args[2:]
- else:
- whitelistmsg = msg
- whitelistargs = args
- if (whitelistmsg % whitelistargs) not in SqueakyCleanLogger.errorWhitelist:
- self.errors.append(msg % args)
- error = warning
-
- def reportGrammarErrors(self):
- if self.errors:
- raise WebIDLError("\n".join(self.errors), [])
-
-class Parser(Tokenizer):
- def getLocation(self, p, i):
- return Location(self.lexer, p.lineno(i), p.lexpos(i), self._filename)
-
- def globalScope(self):
- return self._globalScope
-
- # The p_Foo functions here must match the WebIDL spec's grammar.
- # It's acceptable to split things at '|' boundaries.
- def p_Definitions(self, p):
- """
- Definitions : ExtendedAttributeList Definition Definitions
- """
- if p[2]:
- p[0] = [p[2]]
- p[2].addExtendedAttributes(p[1])
- else:
- assert not p[1]
- p[0] = []
-
- p[0].extend(p[3])
-
- def p_DefinitionsEmpty(self, p):
- """
- Definitions :
- """
- p[0] = []
-
- def p_Definition(self, p):
- """
- Definition : CallbackOrInterface
- | PartialInterface
- | Dictionary
- | Exception
- | Enum
- | Typedef
- | ImplementsStatement
- """
- p[0] = p[1]
- assert p[1] # We might not have implemented something ...
-
- def p_CallbackOrInterfaceCallback(self, p):
- """
- CallbackOrInterface : CALLBACK CallbackRestOrInterface
- """
- if p[2].isInterface():
- assert isinstance(p[2], IDLInterface)
- p[2].setCallback(True)
-
- p[0] = p[2]
-
- def p_CallbackOrInterfaceInterface(self, p):
- """
- CallbackOrInterface : Interface
- """
- p[0] = p[1]
-
- def p_CallbackRestOrInterface(self, p):
- """
- CallbackRestOrInterface : CallbackRest
- | Interface
- """
- assert p[1]
- p[0] = p[1]
-
- def p_Interface(self, p):
- """
- Interface : INTERFACE IDENTIFIER Inheritance LBRACE InterfaceMembers RBRACE SEMICOLON
- """
- location = self.getLocation(p, 1)
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
- members = p[5]
- parent = p[3]
-
- try:
- existingObj = self.globalScope()._lookupIdentifier(identifier)
- if existingObj:
- p[0] = existingObj
- if not isinstance(p[0], IDLInterface):
- raise WebIDLError("Interface has the same name as "
- "non-interface object",
- [location, p[0].location])
- p[0].setNonPartial(location, parent, members)
- return
- except Exception, ex:
- if isinstance(ex, WebIDLError):
- raise ex
- pass
-
- p[0] = IDLInterface(location, self.globalScope(), identifier, parent,
- members, isKnownNonPartial=True)
-
- def p_InterfaceForwardDecl(self, p):
- """
- Interface : INTERFACE IDENTIFIER SEMICOLON
- """
- location = self.getLocation(p, 1)
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
-
- try:
- if self.globalScope()._lookupIdentifier(identifier):
- p[0] = self.globalScope()._lookupIdentifier(identifier)
- if not isinstance(p[0], IDLExternalInterface):
- raise WebIDLError("Name collision between external "
- "interface declaration for identifier "
- "%s and %s" % (identifier.name, p[0]),
- [location, p[0].location])
- return
- except Exception, ex:
- if isinstance(ex, WebIDLError):
- raise ex
- pass
-
- p[0] = IDLExternalInterface(location, self.globalScope(), identifier)
-
- def p_PartialInterface(self, p):
- """
- PartialInterface : PARTIAL INTERFACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON
- """
- location = self.getLocation(p, 2)
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
- members = p[5]
-
- nonPartialInterface = None
- try:
- nonPartialInterface = self.globalScope()._lookupIdentifier(identifier)
- if nonPartialInterface:
- if not isinstance(nonPartialInterface, IDLInterface):
- raise WebIDLError("Partial interface has the same name as "
- "non-interface object",
- [location, nonPartialInterface.location])
- except Exception, ex:
- if isinstance(ex, WebIDLError):
- raise ex
- pass
-
- if not nonPartialInterface:
- nonPartialInterface = IDLInterface(location, self.globalScope(),
- identifier, None,
- [], isKnownNonPartial=False)
- partialInterface = IDLPartialInterface(location, identifier, members,
- nonPartialInterface)
- p[0] = partialInterface
-
- def p_Inheritance(self, p):
- """
- Inheritance : COLON ScopedName
- """
- p[0] = IDLIdentifierPlaceholder(self.getLocation(p, 2), p[2])
-
- def p_InheritanceEmpty(self, p):
- """
- Inheritance :
- """
- pass
-
- def p_InterfaceMembers(self, p):
- """
- InterfaceMembers : ExtendedAttributeList InterfaceMember InterfaceMembers
- """
- p[0] = [p[2]] if p[2] else []
-
- assert not p[1] or p[2]
- p[2].addExtendedAttributes(p[1])
-
- p[0].extend(p[3])
-
- def p_InterfaceMembersEmpty(self, p):
- """
- InterfaceMembers :
- """
- p[0] = []
-
- def p_InterfaceMember(self, p):
- """
- InterfaceMember : Const
- | AttributeOrOperation
- """
- p[0] = p[1]
-
- def p_Dictionary(self, p):
- """
- Dictionary : DICTIONARY IDENTIFIER Inheritance LBRACE DictionaryMembers RBRACE SEMICOLON
- """
- location = self.getLocation(p, 1)
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
- members = p[5]
- p[0] = IDLDictionary(location, self.globalScope(), identifier, p[3], members)
-
- def p_DictionaryMembers(self, p):
- """
- DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers
- |
- """
- if len(p) == 1:
- # We're at the end of the list
- p[0] = []
- return
- # Add our extended attributes
- p[2].addExtendedAttributes(p[1])
- p[0] = [p[2]]
- p[0].extend(p[3])
-
- def p_DictionaryMember(self, p):
- """
- DictionaryMember : Type IDENTIFIER Default SEMICOLON
- """
- # These quack a lot like optional arguments, so just treat them that way.
- t = p[1]
- assert isinstance(t, IDLType)
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
- defaultValue = p[3]
-
- p[0] = IDLArgument(self.getLocation(p, 2), identifier, t, optional=True,
- defaultValue=defaultValue, variadic=False,
- dictionaryMember=True)
-
- def p_Default(self, p):
- """
- Default : EQUALS DefaultValue
- |
- """
- if len(p) > 1:
- p[0] = p[2]
- else:
- p[0] = None
-
- def p_DefaultValue(self, p):
- """
- DefaultValue : ConstValue
- | LBRACKET RBRACKET
- """
- if len(p) == 2:
- p[0] = p[1]
- else:
- assert len(p) == 3 # Must be []
- p[0] = IDLEmptySequenceValue(self.getLocation(p, 1))
-
- def p_Exception(self, p):
- """
- Exception : EXCEPTION IDENTIFIER Inheritance LBRACE ExceptionMembers RBRACE SEMICOLON
- """
- pass
-
- def p_Enum(self, p):
- """
- Enum : ENUM IDENTIFIER LBRACE EnumValueList RBRACE SEMICOLON
- """
- location = self.getLocation(p, 1)
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
-
- values = p[4]
- assert values
- p[0] = IDLEnum(location, self.globalScope(), identifier, values)
-
- def p_EnumValueList(self, p):
- """
- EnumValueList : STRING EnumValueListComma
- """
- p[0] = [p[1]]
- p[0].extend(p[2])
-
- def p_EnumValueListComma(self, p):
- """
- EnumValueListComma : COMMA EnumValueListString
- """
- p[0] = p[2]
-
- def p_EnumValueListCommaEmpty(self, p):
- """
- EnumValueListComma :
- """
- p[0] = []
-
- def p_EnumValueListString(self, p):
- """
- EnumValueListString : STRING EnumValueListComma
- """
- p[0] = [p[1]]
- p[0].extend(p[2])
-
- def p_EnumValueListStringEmpty(self, p):
- """
- EnumValueListString :
- """
- p[0] = []
-
- def p_CallbackRest(self, p):
- """
- CallbackRest : IDENTIFIER EQUALS ReturnType LPAREN ArgumentList RPAREN SEMICOLON
- """
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
- p[0] = IDLCallbackType(self.getLocation(p, 1), self.globalScope(),
- identifier, p[3], p[5])
-
- def p_ExceptionMembers(self, p):
- """
- ExceptionMembers : ExtendedAttributeList ExceptionMember ExceptionMembers
- |
- """
- pass
-
- def p_Typedef(self, p):
- """
- Typedef : TYPEDEF Type IDENTIFIER SEMICOLON
- """
- typedef = IDLTypedefType(self.getLocation(p, 1), p[2], p[3])
- typedef.resolve(self.globalScope())
- p[0] = typedef
-
- def p_ImplementsStatement(self, p):
- """
- ImplementsStatement : ScopedName IMPLEMENTS ScopedName SEMICOLON
- """
- assert(p[2] == "implements")
- implementor = IDLIdentifierPlaceholder(self.getLocation(p, 1), p[1])
- implementee = IDLIdentifierPlaceholder(self.getLocation(p, 3), p[3])
- p[0] = IDLImplementsStatement(self.getLocation(p, 1), implementor,
- implementee)
-
- def p_Const(self, p):
- """
- Const : CONST ConstType IDENTIFIER EQUALS ConstValue SEMICOLON
- """
- location = self.getLocation(p, 1)
- type = p[2]
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
- value = p[5]
- p[0] = IDLConst(location, identifier, type, value)
-
- def p_ConstValueBoolean(self, p):
- """
- ConstValue : BooleanLiteral
- """
- location = self.getLocation(p, 1)
- booleanType = BuiltinTypes[IDLBuiltinType.Types.boolean]
- p[0] = IDLValue(location, booleanType, p[1])
-
- def p_ConstValueInteger(self, p):
- """
- ConstValue : INTEGER
- """
- location = self.getLocation(p, 1)
-
- # We don't know ahead of time what type the integer literal is.
- # Determine the smallest type it could possibly fit in and use that.
- integerType = matchIntegerValueToType(p[1])
- if integerType == None:
- raise WebIDLError("Integer literal out of range", [location])
-
- p[0] = IDLValue(location, integerType, p[1])
-
- def p_ConstValueFloat(self, p):
- """
- ConstValue : FLOATLITERAL
- """
- location = self.getLocation(p, 1)
- p[0] = IDLValue(location, BuiltinTypes[IDLBuiltinType.Types.unrestricted_float], p[1])
-
- def p_ConstValueString(self, p):
- """
- ConstValue : STRING
- """
- location = self.getLocation(p, 1)
- stringType = BuiltinTypes[IDLBuiltinType.Types.domstring]
- p[0] = IDLValue(location, stringType, p[1])
-
- def p_ConstValueNull(self, p):
- """
- ConstValue : NULL
- """
- p[0] = IDLNullValue(self.getLocation(p, 1))
-
- def p_BooleanLiteralTrue(self, p):
- """
- BooleanLiteral : TRUE
- """
- p[0] = True
-
- def p_BooleanLiteralFalse(self, p):
- """
- BooleanLiteral : FALSE
- """
- p[0] = False
-
- def p_AttributeOrOperation(self, p):
- """
- AttributeOrOperation : Attribute
- | Operation
- """
- p[0] = p[1]
-
- def p_AttributeWithQualifier(self, p):
- """
- Attribute : Qualifier AttributeRest
- """
- static = IDLInterfaceMember.Special.Static in p[1]
- stringifier = IDLInterfaceMember.Special.Stringifier in p[1]
- (location, identifier, type, readonly) = p[2]
- p[0] = IDLAttribute(location, identifier, type, readonly, static=static,
- stringifier=stringifier)
-
- def p_Attribute(self, p):
- """
- Attribute : Inherit AttributeRest
- """
- (location, identifier, type, readonly) = p[2]
- p[0] = IDLAttribute(location, identifier, type, readonly, inherit=p[1])
-
- def p_AttributeRest(self, p):
- """
- AttributeRest : ReadOnly ATTRIBUTE Type IDENTIFIER SEMICOLON
- """
- location = self.getLocation(p, 2)
- readonly = p[1]
- t = p[3]
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 4), p[4])
- p[0] = (location, identifier, t, readonly)
-
- def p_ReadOnly(self, p):
- """
- ReadOnly : READONLY
- """
- p[0] = True
-
- def p_ReadOnlyEmpty(self, p):
- """
- ReadOnly :
- """
- p[0] = False
-
- def p_Inherit(self, p):
- """
- Inherit : INHERIT
- """
- p[0] = True
-
- def p_InheritEmpty(self, p):
- """
- Inherit :
- """
- p[0] = False
-
- def p_Operation(self, p):
- """
- Operation : Qualifiers OperationRest
- """
- qualifiers = p[1]
-
- # Disallow duplicates in the qualifier set
- if not len(set(qualifiers)) == len(qualifiers):
- raise WebIDLError("Duplicate qualifiers are not allowed",
- [self.getLocation(p, 1)])
-
- static = IDLInterfaceMember.Special.Static in p[1]
- # If static is there that's all that's allowed. This is disallowed
- # by the parser, so we can assert here.
- assert not static or len(qualifiers) == 1
-
- stringifier = IDLInterfaceMember.Special.Stringifier in p[1]
- # If stringifier is there that's all that's allowed. This is disallowed
- # by the parser, so we can assert here.
- assert not stringifier or len(qualifiers) == 1
-
- getter = True if IDLMethod.Special.Getter in p[1] else False
- setter = True if IDLMethod.Special.Setter in p[1] else False
- creator = True if IDLMethod.Special.Creator in p[1] else False
- deleter = True if IDLMethod.Special.Deleter in p[1] else False
- legacycaller = True if IDLMethod.Special.LegacyCaller in p[1] else False
-
- if getter or deleter:
- if setter or creator:
- raise WebIDLError("getter and deleter are incompatible with setter and creator",
- [self.getLocation(p, 1)])
-
- (returnType, identifier, arguments) = p[2]
-
- assert isinstance(returnType, IDLType)
-
- specialType = IDLMethod.NamedOrIndexed.Neither
-
- if getter or deleter:
- if len(arguments) != 1:
- raise WebIDLError("%s has wrong number of arguments" %
- ("getter" if getter else "deleter"),
- [self.getLocation(p, 2)])
- argType = arguments[0].type
- if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]:
- specialType = IDLMethod.NamedOrIndexed.Named
- elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]:
- specialType = IDLMethod.NamedOrIndexed.Indexed
- else:
- raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" %
- ("getter" if getter else "deleter"),
- [arguments[0].location])
- if arguments[0].optional or arguments[0].variadic:
- raise WebIDLError("%s cannot have %s argument" %
- ("getter" if getter else "deleter",
- "optional" if arguments[0].optional else "variadic"),
- [arguments[0].location])
- if getter:
- if returnType.isVoid():
- raise WebIDLError("getter cannot have void return type",
- [self.getLocation(p, 2)])
- if setter or creator:
- if len(arguments) != 2:
- raise WebIDLError("%s has wrong number of arguments" %
- ("setter" if setter else "creator"),
- [self.getLocation(p, 2)])
- argType = arguments[0].type
- if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]:
- specialType = IDLMethod.NamedOrIndexed.Named
- elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]:
- specialType = IDLMethod.NamedOrIndexed.Indexed
- else:
- raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" %
- ("setter" if setter else "creator"),
- [arguments[0].location])
- if arguments[0].optional or arguments[0].variadic:
- raise WebIDLError("%s cannot have %s argument" %
- ("setter" if setter else "creator",
- "optional" if arguments[0].optional else "variadic"),
- [arguments[0].location])
- if arguments[1].optional or arguments[1].variadic:
- raise WebIDLError("%s cannot have %s argument" %
- ("setter" if setter else "creator",
- "optional" if arguments[1].optional else "variadic"),
- [arguments[1].location])
-
- if stringifier:
- if len(arguments) != 0:
- raise WebIDLError("stringifier has wrong number of arguments",
- [self.getLocation(p, 2)])
- if not returnType.isDOMString():
- raise WebIDLError("stringifier must have DOMString return type",
- [self.getLocation(p, 2)])
-
- # identifier might be None. This is only permitted for special methods.
- if not identifier:
- if not getter and not setter and not creator and \
- not deleter and not legacycaller and not stringifier:
- raise WebIDLError("Identifier required for non-special methods",
- [self.getLocation(p, 2)])
-
- location = BuiltinLocation("<auto-generated-identifier>")
- identifier = IDLUnresolvedIdentifier(location, "__%s%s%s%s%s%s%s" %
- ("named" if specialType == IDLMethod.NamedOrIndexed.Named else \
- "indexed" if specialType == IDLMethod.NamedOrIndexed.Indexed else "",
- "getter" if getter else "",
- "setter" if setter else "",
- "deleter" if deleter else "",
- "creator" if creator else "",
- "legacycaller" if legacycaller else "",
- "stringifier" if stringifier else ""), allowDoubleUnderscore=True)
-
- method = IDLMethod(self.getLocation(p, 2), identifier, returnType, arguments,
- static=static, getter=getter, setter=setter, creator=creator,
- deleter=deleter, specialType=specialType,
- legacycaller=legacycaller, stringifier=stringifier)
- p[0] = method
-
- def p_Stringifier(self, p):
- """
- Operation : STRINGIFIER SEMICOLON
- """
- identifier = IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
- "__stringifier",
- allowDoubleUnderscore=True)
- method = IDLMethod(self.getLocation(p, 1),
- identifier,
- returnType=BuiltinTypes[IDLBuiltinType.Types.domstring],
- arguments=[],
- stringifier=True)
- p[0] = method
-
- def p_Jsonifier(self, p):
- """
- Operation : JSONIFIER SEMICOLON
- """
- identifier = IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
- "__jsonifier", allowDoubleUnderscore=True)
- method = IDLMethod(self.getLocation(p, 1),
- identifier,
- returnType=BuiltinTypes[IDLBuiltinType.Types.object],
- arguments=[],
- jsonifier=True)
- p[0] = method
-
- def p_QualifierStatic(self, p):
- """
- Qualifier : STATIC
- """
- p[0] = [IDLInterfaceMember.Special.Static]
-
- def p_QualifierStringifier(self, p):
- """
- Qualifier : STRINGIFIER
- """
- p[0] = [IDLInterfaceMember.Special.Stringifier]
-
- def p_Qualifiers(self, p):
- """
- Qualifiers : Qualifier
- | Specials
- """
- p[0] = p[1]
-
- def p_Specials(self, p):
- """
- Specials : Special Specials
- """
- p[0] = [p[1]]
- p[0].extend(p[2])
-
- def p_SpecialsEmpty(self, p):
- """
- Specials :
- """
- p[0] = []
-
- def p_SpecialGetter(self, p):
- """
- Special : GETTER
- """
- p[0] = IDLMethod.Special.Getter
-
- def p_SpecialSetter(self, p):
- """
- Special : SETTER
- """
- p[0] = IDLMethod.Special.Setter
-
- def p_SpecialCreator(self, p):
- """
- Special : CREATOR
- """
- p[0] = IDLMethod.Special.Creator
-
- def p_SpecialDeleter(self, p):
- """
- Special : DELETER
- """
- p[0] = IDLMethod.Special.Deleter
-
- def p_SpecialLegacyCaller(self, p):
- """
- Special : LEGACYCALLER
- """
- p[0] = IDLMethod.Special.LegacyCaller
-
- def p_OperationRest(self, p):
- """
- OperationRest : ReturnType OptionalIdentifier LPAREN ArgumentList RPAREN SEMICOLON
- """
- p[0] = (p[1], p[2], p[4])
-
- def p_OptionalIdentifier(self, p):
- """
- OptionalIdentifier : IDENTIFIER
- """
- p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
-
- def p_OptionalIdentifierEmpty(self, p):
- """
- OptionalIdentifier :
- """
- pass
-
- def p_ArgumentList(self, p):
- """
- ArgumentList : Argument Arguments
- """
- p[0] = [p[1]] if p[1] else []
- p[0].extend(p[2])
-
- def p_ArgumentListEmpty(self, p):
- """
- ArgumentList :
- """
- p[0] = []
-
- def p_Arguments(self, p):
- """
- Arguments : COMMA Argument Arguments
- """
- p[0] = [p[2]] if p[2] else []
- p[0].extend(p[3])
-
- def p_ArgumentsEmpty(self, p):
- """
- Arguments :
- """
- p[0] = []
-
- def p_Argument(self, p):
- """
- Argument : ExtendedAttributeList Optional Type Ellipsis ArgumentName Default
- """
- t = p[3]
- assert isinstance(t, IDLType)
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 5), p[5])
-
- optional = p[2]
- variadic = p[4]
- defaultValue = p[6]
-
- if not optional and defaultValue:
- raise WebIDLError("Mandatory arguments can't have a default value.",
- [self.getLocation(p, 6)])
-
- # We can't test t.isAny() here and give it a default value as needed,
- # since at this point t is not a fully resolved type yet (e.g. it might
- # be a typedef). We'll handle the 'any' case in IDLArgument.complete.
-
- if variadic:
- if optional:
- raise WebIDLError("Variadic arguments should not be marked optional.",
- [self.getLocation(p, 2)])
- optional = variadic
-
- p[0] = IDLArgument(self.getLocation(p, 5), identifier, t, optional, defaultValue, variadic)
- p[0].addExtendedAttributes(p[1])
-
- def p_ArgumentName(self, p):
- """
- ArgumentName : IDENTIFIER
- | ATTRIBUTE
- | CALLBACK
- | CONST
- | CREATOR
- | DELETER
- | DICTIONARY
- | ENUM
- | EXCEPTION
- | GETTER
- | IMPLEMENTS
- | INHERIT
- | INTERFACE
- | LEGACYCALLER
- | PARTIAL
- | SERIALIZER
- | SETTER
- | STATIC
- | STRINGIFIER
- | JSONIFIER
- | TYPEDEF
- | UNRESTRICTED
- """
- p[0] = p[1]
-
- def p_Optional(self, p):
- """
- Optional : OPTIONAL
- """
- p[0] = True
-
- def p_OptionalEmpty(self, p):
- """
- Optional :
- """
- p[0] = False
-
- def p_Ellipsis(self, p):
- """
- Ellipsis : ELLIPSIS
- """
- p[0] = True
-
- def p_EllipsisEmpty(self, p):
- """
- Ellipsis :
- """
- p[0] = False
-
- def p_ExceptionMember(self, p):
- """
- ExceptionMember : Const
- | ExceptionField
- """
- pass
-
- def p_ExceptionField(self, p):
- """
- ExceptionField : Type IDENTIFIER SEMICOLON
- """
- pass
-
- def p_ExtendedAttributeList(self, p):
- """
- ExtendedAttributeList : LBRACKET ExtendedAttribute ExtendedAttributes RBRACKET
- """
- p[0] = [p[2]]
- if p[3]:
- p[0].extend(p[3])
-
- def p_ExtendedAttributeListEmpty(self, p):
- """
- ExtendedAttributeList :
- """
- p[0] = []
-
- def p_ExtendedAttribute(self, p):
- """
- ExtendedAttribute : ExtendedAttributeNoArgs
- | ExtendedAttributeArgList
- | ExtendedAttributeIdent
- | ExtendedAttributeNamedArgList
- | ExtendedAttributeIdentList
- """
- p[0] = IDLExtendedAttribute(self.getLocation(p, 1), p[1])
-
- def p_ExtendedAttributeEmpty(self, p):
- """
- ExtendedAttribute :
- """
- pass
-
- def p_ExtendedAttributes(self, p):
- """
- ExtendedAttributes : COMMA ExtendedAttribute ExtendedAttributes
- """
- p[0] = [p[2]] if p[2] else []
- p[0].extend(p[3])
-
- def p_ExtendedAttributesEmpty(self, p):
- """
- ExtendedAttributes :
- """
- p[0] = []
-
- def p_Other(self, p):
- """
- Other : INTEGER
- | FLOATLITERAL
- | IDENTIFIER
- | STRING
- | OTHER
- | ELLIPSIS
- | COLON
- | SCOPE
- | SEMICOLON
- | LT
- | EQUALS
- | GT
- | QUESTIONMARK
- | DATE
- | DOMSTRING
- | BYTESTRING
- | SCALARVALUESTRING
- | ANY
- | ATTRIBUTE
- | BOOLEAN
- | BYTE
- | LEGACYCALLER
- | CONST
- | CREATOR
- | DELETER
- | DOUBLE
- | EXCEPTION
- | FALSE
- | FLOAT
- | GETTER
- | IMPLEMENTS
- | INHERIT
- | INTERFACE
- | LONG
- | MODULE
- | NULL
- | OBJECT
- | OCTET
- | OPTIONAL
- | SEQUENCE
- | MOZMAP
- | SETTER
- | SHORT
- | STATIC
- | STRINGIFIER
- | JSONIFIER
- | TRUE
- | TYPEDEF
- | UNSIGNED
- | VOID
- """
- pass
-
- def p_OtherOrComma(self, p):
- """
- OtherOrComma : Other
- | COMMA
- """
- pass
-
- def p_TypeSingleType(self, p):
- """
- Type : SingleType
- """
- p[0] = p[1]
-
- def p_TypeUnionType(self, p):
- """
- Type : UnionType TypeSuffix
- """
- p[0] = self.handleModifiers(p[1], p[2])
-
- def p_SingleTypeNonAnyType(self, p):
- """
- SingleType : NonAnyType
- """
- p[0] = p[1]
-
- def p_SingleTypeAnyType(self, p):
- """
- SingleType : ANY TypeSuffixStartingWithArray
- """
- p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.any], p[2])
-
- def p_UnionType(self, p):
- """
- UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN
- """
- types = [p[2], p[4]]
- types.extend(p[5])
- p[0] = IDLUnionType(self.getLocation(p, 1), types)
-
- def p_UnionMemberTypeNonAnyType(self, p):
- """
- UnionMemberType : NonAnyType
- """
- p[0] = p[1]
-
- def p_UnionMemberTypeArrayOfAny(self, p):
- """
- UnionMemberTypeArrayOfAny : ANY LBRACKET RBRACKET
- """
- p[0] = IDLArrayType(self.getLocation(p, 2),
- BuiltinTypes[IDLBuiltinType.Types.any])
-
- def p_UnionMemberType(self, p):
- """
- UnionMemberType : UnionType TypeSuffix
- | UnionMemberTypeArrayOfAny TypeSuffix
- """
- p[0] = self.handleModifiers(p[1], p[2])
-
- def p_UnionMemberTypes(self, p):
- """
- UnionMemberTypes : OR UnionMemberType UnionMemberTypes
- """
- p[0] = [p[2]]
- p[0].extend(p[3])
-
- def p_UnionMemberTypesEmpty(self, p):
- """
- UnionMemberTypes :
- """
- p[0] = []
-
- def p_NonAnyType(self, p):
- """
- NonAnyType : PrimitiveOrStringType TypeSuffix
- | ARRAYBUFFER TypeSuffix
- | OBJECT TypeSuffix
- """
- if p[1] == "object":
- type = BuiltinTypes[IDLBuiltinType.Types.object]
- elif p[1] == "ArrayBuffer":
- type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer]
- else:
- type = BuiltinTypes[p[1]]
-
- p[0] = self.handleModifiers(type, p[2])
-
- def p_NonAnyTypeSequenceType(self, p):
- """
- NonAnyType : SEQUENCE LT Type GT Null
- """
- innerType = p[3]
- type = IDLSequenceType(self.getLocation(p, 1), innerType)
- if p[5]:
- type = IDLNullableType(self.getLocation(p, 5), type)
- p[0] = type
-
- # Note: Promise<void> is allowed, so we want to parametrize on
- # ReturnType, not Type. Also, we want this to end up picking up
- # the Promise interface for now, hence the games with IDLUnresolvedType.
- def p_NonAnyTypePromiseType(self, p):
- """
- NonAnyType : PROMISE LT ReturnType GT Null
- """
- innerType = p[3]
- promiseIdent = IDLUnresolvedIdentifier(self.getLocation(p, 1), "Promise")
- type = IDLUnresolvedType(self.getLocation(p, 1), promiseIdent, p[3])
- if p[5]:
- type = IDLNullableType(self.getLocation(p, 5), type)
- p[0] = type
-
- def p_NonAnyTypeMozMapType(self, p):
- """
- NonAnyType : MOZMAP LT Type GT Null
- """
- innerType = p[3]
- type = IDLMozMapType(self.getLocation(p, 1), innerType)
- if p[5]:
- type = IDLNullableType(self.getLocation(p, 5), type)
- p[0] = type
-
- def p_NonAnyTypeScopedName(self, p):
- """
- NonAnyType : ScopedName TypeSuffix
- """
- assert isinstance(p[1], IDLUnresolvedIdentifier)
-
- if p[1].name == "Promise":
- raise WebIDLError("Promise used without saying what it's "
- "parametrized over",
- [self.getLocation(p, 1)])
-
- type = None
-
- try:
- if self.globalScope()._lookupIdentifier(p[1]):
- obj = self.globalScope()._lookupIdentifier(p[1])
- if obj.isType():
- type = obj
- else:
- type = IDLWrapperType(self.getLocation(p, 1), p[1])
- p[0] = self.handleModifiers(type, p[2])
- return
- except:
- pass
-
- type = IDLUnresolvedType(self.getLocation(p, 1), p[1])
- p[0] = self.handleModifiers(type, p[2])
-
- def p_NonAnyTypeDate(self, p):
- """
- NonAnyType : DATE TypeSuffix
- """
- p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.date],
- p[2])
-
- def p_ConstType(self, p):
- """
- ConstType : PrimitiveOrStringType Null
- """
- type = BuiltinTypes[p[1]]
- if p[2]:
- type = IDLNullableType(self.getLocation(p, 1), type)
- p[0] = type
-
- def p_ConstTypeIdentifier(self, p):
- """
- ConstType : IDENTIFIER Null
- """
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
-
- type = IDLUnresolvedType(self.getLocation(p, 1), identifier)
- if p[2]:
- type = IDLNullableType(self.getLocation(p, 1), type)
- p[0] = type
-
- def p_PrimitiveOrStringTypeUint(self, p):
- """
- PrimitiveOrStringType : UnsignedIntegerType
- """
- p[0] = p[1]
-
- def p_PrimitiveOrStringTypeBoolean(self, p):
- """
- PrimitiveOrStringType : BOOLEAN
- """
- p[0] = IDLBuiltinType.Types.boolean
-
- def p_PrimitiveOrStringTypeByte(self, p):
- """
- PrimitiveOrStringType : BYTE
- """
- p[0] = IDLBuiltinType.Types.byte
-
- def p_PrimitiveOrStringTypeOctet(self, p):
- """
- PrimitiveOrStringType : OCTET
- """
- p[0] = IDLBuiltinType.Types.octet
-
- def p_PrimitiveOrStringTypeFloat(self, p):
- """
- PrimitiveOrStringType : FLOAT
- """
- p[0] = IDLBuiltinType.Types.float
-
- def p_PrimitiveOrStringTypeUnrestictedFloat(self, p):
- """
- PrimitiveOrStringType : UNRESTRICTED FLOAT
- """
- p[0] = IDLBuiltinType.Types.unrestricted_float
-
- def p_PrimitiveOrStringTypeDouble(self, p):
- """
- PrimitiveOrStringType : DOUBLE
- """
- p[0] = IDLBuiltinType.Types.double
-
- def p_PrimitiveOrStringTypeUnrestictedDouble(self, p):
- """
- PrimitiveOrStringType : UNRESTRICTED DOUBLE
- """
- p[0] = IDLBuiltinType.Types.unrestricted_double
-
- def p_PrimitiveOrStringTypeDOMString(self, p):
- """
- PrimitiveOrStringType : DOMSTRING
- """
- p[0] = IDLBuiltinType.Types.domstring
-
- def p_PrimitiveOrStringTypeBytestring(self, p):
- """
- PrimitiveOrStringType : BYTESTRING
- """
- p[0] = IDLBuiltinType.Types.bytestring
-
- def p_PrimitiveOrStringTypeScalarValueString(self, p):
- """
- PrimitiveOrStringType : SCALARVALUESTRING
- """
- p[0] = IDLBuiltinType.Types.scalarvaluestring
-
- def p_UnsignedIntegerTypeUnsigned(self, p):
- """
- UnsignedIntegerType : UNSIGNED IntegerType
- """
- p[0] = p[2] + 1 # Adding one to a given signed integer type
- # gets you the unsigned type.
-
- def p_UnsignedIntegerType(self, p):
- """
- UnsignedIntegerType : IntegerType
- """
- p[0] = p[1]
-
- def p_IntegerTypeShort(self, p):
- """
- IntegerType : SHORT
- """
- p[0] = IDLBuiltinType.Types.short
-
- def p_IntegerTypeLong(self, p):
- """
- IntegerType : LONG OptionalLong
- """
- if p[2]:
- p[0] = IDLBuiltinType.Types.long_long
- else:
- p[0] = IDLBuiltinType.Types.long
-
- def p_OptionalLong(self, p):
- """
- OptionalLong : LONG
- """
- p[0] = True
-
- def p_OptionalLongEmpty(self, p):
- """
- OptionalLong :
- """
- p[0] = False
-
- def p_TypeSuffixBrackets(self, p):
- """
- TypeSuffix : LBRACKET RBRACKET TypeSuffix
- """
- p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
- p[0].extend(p[3])
-
- def p_TypeSuffixQMark(self, p):
- """
- TypeSuffix : QUESTIONMARK TypeSuffixStartingWithArray
- """
- p[0] = [(IDLMethod.TypeSuffixModifier.QMark, self.getLocation(p, 1))]
- p[0].extend(p[2])
-
- def p_TypeSuffixEmpty(self, p):
- """
- TypeSuffix :
- """
- p[0] = []
-
- def p_TypeSuffixStartingWithArray(self, p):
- """
- TypeSuffixStartingWithArray : LBRACKET RBRACKET TypeSuffix
- """
- p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
- p[0].extend(p[3])
-
- def p_TypeSuffixStartingWithArrayEmpty(self, p):
- """
- TypeSuffixStartingWithArray :
- """
- p[0] = []
-
- def p_Null(self, p):
- """
- Null : QUESTIONMARK
- |
- """
- if len(p) > 1:
- p[0] = True
- else:
- p[0] = False
-
- def p_ReturnTypeType(self, p):
- """
- ReturnType : Type
- """
- p[0] = p[1]
-
- def p_ReturnTypeVoid(self, p):
- """
- ReturnType : VOID
- """
- p[0] = BuiltinTypes[IDLBuiltinType.Types.void]
-
- def p_ScopedName(self, p):
- """
- ScopedName : AbsoluteScopedName
- | RelativeScopedName
- """
- p[0] = p[1]
-
- def p_AbsoluteScopedName(self, p):
- """
- AbsoluteScopedName : SCOPE IDENTIFIER ScopedNameParts
- """
- assert False
- pass
-
- def p_RelativeScopedName(self, p):
- """
- RelativeScopedName : IDENTIFIER ScopedNameParts
- """
- assert not p[2] # Not implemented!
-
- p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
-
- def p_ScopedNameParts(self, p):
- """
- ScopedNameParts : SCOPE IDENTIFIER ScopedNameParts
- """
- assert False
- pass
-
- def p_ScopedNamePartsEmpty(self, p):
- """
- ScopedNameParts :
- """
- p[0] = None
-
- def p_ExtendedAttributeNoArgs(self, p):
- """
- ExtendedAttributeNoArgs : IDENTIFIER
- """
- p[0] = (p[1],)
-
- def p_ExtendedAttributeArgList(self, p):
- """
- ExtendedAttributeArgList : IDENTIFIER LPAREN ArgumentList RPAREN
- """
- p[0] = (p[1], p[3])
-
- def p_ExtendedAttributeIdent(self, p):
- """
- ExtendedAttributeIdent : IDENTIFIER EQUALS STRING
- | IDENTIFIER EQUALS IDENTIFIER
- """
- p[0] = (p[1], p[3])
-
- def p_ExtendedAttributeNamedArgList(self, p):
- """
- ExtendedAttributeNamedArgList : IDENTIFIER EQUALS IDENTIFIER LPAREN ArgumentList RPAREN
- """
- p[0] = (p[1], p[3], p[5])
-
- def p_ExtendedAttributeIdentList(self, p):
- """
- ExtendedAttributeIdentList : IDENTIFIER EQUALS LPAREN IdentifierList RPAREN
- """
- p[0] = (p[1], p[4])
-
- def p_IdentifierList(self, p):
- """
- IdentifierList : IDENTIFIER Identifiers
- """
- idents = list(p[2])
- idents.insert(0, p[1])
- p[0] = idents
-
- def p_IdentifiersList(self, p):
- """
- Identifiers : COMMA IDENTIFIER Identifiers
- """
- idents = list(p[3])
- idents.insert(0, p[2])
- p[0] = idents
-
- def p_IdentifiersEmpty(self, p):
- """
- Identifiers :
- """
- p[0] = []
-
- def p_error(self, p):
- if not p:
- raise WebIDLError("Syntax Error at end of file. Possibly due to missing semicolon(;), braces(}) or both",
- [self._filename])
- else:
- raise WebIDLError("invalid syntax", [Location(self.lexer, p.lineno, p.lexpos, self._filename)])
-
- def __init__(self, outputdir='', lexer=None):
- Tokenizer.__init__(self, outputdir, lexer)
-
- logger = SqueakyCleanLogger()
- self.parser = yacc.yacc(module=self,
- outputdir=outputdir,
- tabmodule='webidlyacc',
- errorlog=logger
- # Pickling the grammar is a speedup in
- # some cases (older Python?) but a
- # significant slowdown in others.
- # We're not pickling for now, until it
- # becomes a speedup again.
- # , picklefile='WebIDLGrammar.pkl'
- )
- logger.reportGrammarErrors()
-
- self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
- # To make our test harness work, pretend like we have a primary global already. Note that we _don't_ set _globalScope.primaryGlobalAttr, so we'll still be able to detect multiple PrimaryGlobal extended attributes.
- self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
- self._globalScope.globalNames.add("FakeTestPrimaryGlobal")
- self._globalScope.globalNameMapping["FakeTestPrimaryGlobal"].add("FakeTestPrimaryGlobal")
- self._installBuiltins(self._globalScope)
- self._productions = []
-
- self._filename = "<builtin>"
- self.lexer.input(Parser._builtins)
- self._filename = None
-
- self.parser.parse(lexer=self.lexer,tracking=True)
-
- def _installBuiltins(self, scope):
- assert isinstance(scope, IDLScope)
-
- # xrange omits the last value.
- for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1):
- builtin = BuiltinTypes[x]
- name = builtin.name
-
- typedef = IDLTypedefType(BuiltinLocation("<builtin type>"), builtin, name)
- typedef.resolve(scope)
-
- @ staticmethod
- def handleModifiers(type, modifiers):
- for (modifier, modifierLocation) in modifiers:
- assert modifier == IDLMethod.TypeSuffixModifier.QMark or \
- modifier == IDLMethod.TypeSuffixModifier.Brackets
-
- if modifier == IDLMethod.TypeSuffixModifier.QMark:
- type = IDLNullableType(modifierLocation, type)
- elif modifier == IDLMethod.TypeSuffixModifier.Brackets:
- type = IDLArrayType(modifierLocation, type)
-
- return type
-
- def parse(self, t, filename=None):
- self.lexer.input(t)
-
- #for tok in iter(self.lexer.token, None):
- # print tok
-
- self._filename = filename
- self._productions.extend(self.parser.parse(lexer=self.lexer,tracking=True))
- self._filename = None
-
- def finish(self):
- # First, finish all the IDLImplementsStatements. In particular, we
- # have to make sure we do those before we do the IDLInterfaces.
- # XXX khuey hates this bit and wants to nuke it from orbit.
- implementsStatements = [ p for p in self._productions if
- isinstance(p, IDLImplementsStatement)]
- otherStatements = [ p for p in self._productions if
- not isinstance(p, IDLImplementsStatement)]
- for production in implementsStatements:
- production.finish(self.globalScope())
- for production in otherStatements:
- production.finish(self.globalScope())
-
- # Do any post-finish validation we need to do
- for production in self._productions:
- production.validate()
-
- # De-duplicate self._productions, without modifying its order.
- seen = set()
- result = []
- for p in self._productions:
- if p not in seen:
- seen.add(p)
- result.append(p)
- return result
-
- def reset(self):
- return Parser(lexer=self.lexer)
-
- # Builtin IDL defined by WebIDL
- _builtins = """
- typedef unsigned long long DOMTimeStamp;
- """
-
-def main():
- # Parse arguments.
- from optparse import OptionParser
- usageString = "usage: %prog [options] files"
- o = OptionParser(usage=usageString)
- o.add_option("--cachedir", dest='cachedir', default=None,
- help="Directory in which to cache lex/parse tables.")
- o.add_option("--verbose-errors", action='store_true', default=False,
- help="When an error happens, display the Python traceback.")
- (options, args) = o.parse_args()
-
- if len(args) < 1:
- o.error(usageString)
-
- fileList = args
- baseDir = os.getcwd()
-
- # Parse the WebIDL.
- parser = Parser(options.cachedir)
- try:
- for filename in fileList:
- fullPath = os.path.normpath(os.path.join(baseDir, filename))
- f = open(fullPath, 'rb')
- lines = f.readlines()
- f.close()
- print fullPath
- parser.parse(''.join(lines), fullPath)
- parser.finish()
- except WebIDLError, e:
- if options.verbose_errors:
- traceback.print_exc()
- else:
- print e
-
-if __name__ == '__main__':
- main()
diff --git a/src/components/script/dom/bindings/codegen/parser/external.patch b/src/components/script/dom/bindings/codegen/parser/external.patch
deleted file mode 100644
index 9464511a9d0..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/external.patch
+++ /dev/null
@@ -1,49 +0,0 @@
---- WebIDL.py
-+++ WebIDL.py
-@@ -450,44 +450,8 @@ class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
-
- class IDLExternalInterface(IDLObjectWithIdentifier):
- def __init__(self, location, parentScope, identifier):
-- assert isinstance(identifier, IDLUnresolvedIdentifier)
-- assert isinstance(parentScope, IDLScope)
-- self.parent = None
-- IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
-- IDLObjectWithIdentifier.resolve(self, parentScope)
--
-- def finish(self, scope):
-- pass
--
-- def validate(self):
-- pass
--
-- def isExternal(self):
-- return True
--
-- def isInterface(self):
-- return True
--
-- def isConsequential(self):
-- return False
--
-- def addExtendedAttributes(self, attrs):
-- assert len(attrs) == 0
--
-- def resolve(self, parentScope):
-- pass
--
-- def getJSImplementation(self):
-- return None
--
-- def isJSImplemented(self):
-- return False
--
-- def getNavigatorProperty(self):
-- return None
--
-- def _getDependentObjects(self):
-- return set()
-+ raise WebIDLError("Servo does not support external interfaces.",
-+ [self.location])
-
- class IDLPartialInterface(IDLObject):
- def __init__(self, location, name, members, nonPartialInterface):
diff --git a/src/components/script/dom/bindings/codegen/parser/module.patch b/src/components/script/dom/bindings/codegen/parser/module.patch
deleted file mode 100644
index 977947b4c63..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/module.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- WebIDL.py
-+++ WebIDL.py
-@@ -3398,6 +3398,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
- self._treatNonCallableAsNull = False
- self._treatNonObjectAsNull = False
-
-+ def module(self):
-+ return self.location.filename().split('/')[-1].split('.webidl')[0] + 'Binding'
-+
- def isCallback(self):
- return True
-
diff --git a/src/components/script/dom/bindings/codegen/parser/runtests.py b/src/components/script/dom/bindings/codegen/parser/runtests.py
deleted file mode 100644
index 98a7d2b81d3..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/runtests.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# 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 os, sys
-import glob
-import optparse
-import traceback
-import WebIDL
-
-class TestHarness(object):
- def __init__(self, test, verbose):
- self.test = test
- self.verbose = verbose
- self.printed_intro = False
-
- def start(self):
- if self.verbose:
- self.maybe_print_intro()
-
- def finish(self):
- if self.verbose or self.printed_intro:
- print "Finished test %s" % self.test
-
- def maybe_print_intro(self):
- if not self.printed_intro:
- print "Starting test %s" % self.test
- self.printed_intro = True
-
- def test_pass(self, msg):
- if self.verbose:
- print "TEST-PASS | %s" % msg
-
- def test_fail(self, msg):
- self.maybe_print_intro()
- print "TEST-UNEXPECTED-FAIL | %s" % msg
-
- def ok(self, condition, msg):
- if condition:
- self.test_pass(msg)
- else:
- self.test_fail(msg)
-
- def check(self, a, b, msg):
- if a == b:
- self.test_pass(msg)
- else:
- self.test_fail(msg)
- print "\tGot %s expected %s" % (a, b)
-
-def run_tests(tests, verbose):
- testdir = os.path.join(os.path.dirname(__file__), 'tests')
- if not tests:
- tests = glob.iglob(os.path.join(testdir, "*.py"))
- sys.path.append(testdir)
-
- for test in tests:
- (testpath, ext) = os.path.splitext(os.path.basename(test))
- _test = __import__(testpath, globals(), locals(), ['WebIDLTest'])
-
- harness = TestHarness(test, verbose)
- harness.start()
- try:
- _test.WebIDLTest.__call__(WebIDL.Parser(), harness)
- except Exception, ex:
- print "TEST-UNEXPECTED-FAIL | Unhandled exception in test %s: %s" % (testpath, ex)
- traceback.print_exc()
- finally:
- harness.finish()
-
-if __name__ == '__main__':
- usage = """%prog [OPTIONS] [TESTS]
- Where TESTS are relative to the tests directory."""
- parser = optparse.OptionParser(usage=usage)
- parser.add_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
- help="Don't print passing tests.")
- options, tests = parser.parse_args()
-
- run_tests(tests, verbose=options.verbose)
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_any_null.py b/src/components/script/dom/bindings/codegen/parser/tests/test_any_null.py
deleted file mode 100644
index e3b690bf6f1..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_any_null.py
+++ /dev/null
@@ -1,14 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface DoubleNull {
- attribute any? foo;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py b/src/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py
deleted file mode 100644
index eb1f6d3c92e..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py
+++ /dev/null
@@ -1,14 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface ArgumentIdentifierConflict {
- void foo(boolean arg1, boolean arg1);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py b/src/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py
deleted file mode 100644
index ef8c2229aed..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py
+++ /dev/null
@@ -1,14 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface VoidArgument1 {
- void foo(void arg2);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py b/src/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py
deleted file mode 100644
index 26528984595..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface A {
- attribute long a;
- };
-
- interface B {
- attribute A[] b;
- };
- """);
- parser.finish()
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py b/src/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py
deleted file mode 100644
index 5b8e56f86ca..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestArrayBuffer {
- attribute ArrayBuffer bufferAttr;
- void bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, ArrayBuffer[] arg3, sequence<ArrayBuffer> arg4);
-
- attribute ArrayBufferView viewAttr;
- void viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, ArrayBufferView[] arg3, sequence<ArrayBufferView> arg4);
-
- attribute Int8Array int8ArrayAttr;
- void int8ArrayMethod(Int8Array arg1, Int8Array? arg2, Int8Array[] arg3, sequence<Int8Array> arg4);
-
- attribute Uint8Array uint8ArrayAttr;
- void uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, Uint8Array[] arg3, sequence<Uint8Array> arg4);
-
- attribute Uint8ClampedArray uint8ClampedArrayAttr;
- void uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, Uint8ClampedArray[] arg3, sequence<Uint8ClampedArray> arg4);
-
- attribute Int16Array int16ArrayAttr;
- void int16ArrayMethod(Int16Array arg1, Int16Array? arg2, Int16Array[] arg3, sequence<Int16Array> arg4);
-
- attribute Uint16Array uint16ArrayAttr;
- void uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, Uint16Array[] arg3, sequence<Uint16Array> arg4);
-
- attribute Int32Array int32ArrayAttr;
- void int32ArrayMethod(Int32Array arg1, Int32Array? arg2, Int32Array[] arg3, sequence<Int32Array> arg4);
-
- attribute Uint32Array uint32ArrayAttr;
- void uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, Uint32Array[] arg3, sequence<Uint32Array> arg4);
-
- attribute Float32Array float32ArrayAttr;
- void float32ArrayMethod(Float32Array arg1, Float32Array? arg2, Float32Array[] arg3, sequence<Float32Array> arg4);
-
- attribute Float64Array float64ArrayAttr;
- void float64ArrayMethod(Float64Array arg1, Float64Array? arg2, Float64Array[] arg3, sequence<Float64Array> arg4);
- };
- """)
-
- results = parser.finish()
-
- iface = results[0]
-
- harness.ok(True, "TestArrayBuffer interface parsed without error")
- harness.check(len(iface.members), 22, "Interface should have twenty two members")
-
- members = iface.members
-
- def checkStuff(attr, method, t):
- harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Expect an IDLAttribute")
- harness.ok(isinstance(method, WebIDL.IDLMethod), "Expect an IDLMethod")
-
- harness.check(str(attr.type), t, "Expect an ArrayBuffer type")
- harness.ok(attr.type.isSpiderMonkeyInterface(), "Should test as a js interface")
-
- (retType, arguments) = method.signatures()[0]
- harness.ok(retType.isVoid(), "Should have a void return type")
- harness.check(len(arguments), 4, "Expect 4 arguments")
-
- harness.check(str(arguments[0].type), t, "Expect an ArrayBuffer type")
- harness.ok(arguments[0].type.isSpiderMonkeyInterface(), "Should test as a js interface")
-
- harness.check(str(arguments[1].type), t + "OrNull", "Expect an ArrayBuffer type")
- harness.ok(arguments[1].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
-
- harness.check(str(arguments[2].type), t + "Array", "Expect an ArrayBuffer type")
- harness.ok(arguments[2].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
-
- harness.check(str(arguments[3].type), t + "Sequence", "Expect an ArrayBuffer type")
- harness.ok(arguments[3].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
-
-
- checkStuff(members[0], members[1], "ArrayBuffer")
- checkStuff(members[2], members[3], "ArrayBufferView")
- checkStuff(members[4], members[5], "Int8Array")
- checkStuff(members[6], members[7], "Uint8Array")
- checkStuff(members[8], members[9], "Uint8ClampedArray")
- checkStuff(members[10], members[11], "Int16Array")
- checkStuff(members[12], members[13], "Uint16Array")
- checkStuff(members[14], members[15], "Int32Array")
- checkStuff(members[16], members[17], "Uint32Array")
- checkStuff(members[18], members[19], "Float32Array")
- checkStuff(members[20], members[21], "Float64Array")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_attr.py b/src/components/script/dom/bindings/codegen/parser/tests/test_attr.py
deleted file mode 100644
index 6b6142b6243..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_attr.py
+++ /dev/null
@@ -1,302 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- testData = [("::TestAttr%s::b", "b", "Byte%s", False),
- ("::TestAttr%s::rb", "rb", "Byte%s", True),
- ("::TestAttr%s::o", "o", "Octet%s", False),
- ("::TestAttr%s::ro", "ro", "Octet%s", True),
- ("::TestAttr%s::s", "s", "Short%s", False),
- ("::TestAttr%s::rs", "rs", "Short%s", True),
- ("::TestAttr%s::us", "us", "UnsignedShort%s", False),
- ("::TestAttr%s::rus", "rus", "UnsignedShort%s", True),
- ("::TestAttr%s::l", "l", "Long%s", False),
- ("::TestAttr%s::rl", "rl", "Long%s", True),
- ("::TestAttr%s::ul", "ul", "UnsignedLong%s", False),
- ("::TestAttr%s::rul", "rul", "UnsignedLong%s", True),
- ("::TestAttr%s::ll", "ll", "LongLong%s", False),
- ("::TestAttr%s::rll", "rll", "LongLong%s", True),
- ("::TestAttr%s::ull", "ull", "UnsignedLongLong%s", False),
- ("::TestAttr%s::rull", "rull", "UnsignedLongLong%s", True),
- ("::TestAttr%s::str", "str", "String%s", False),
- ("::TestAttr%s::rstr", "rstr", "String%s", True),
- ("::TestAttr%s::obj", "obj", "Object%s", False),
- ("::TestAttr%s::robj", "robj", "Object%s", True),
- ("::TestAttr%s::object", "object", "Object%s", False),
- ("::TestAttr%s::f", "f", "Float%s", False),
- ("::TestAttr%s::rf", "rf", "Float%s", True)]
-
- parser.parse("""
- interface TestAttr {
- attribute byte b;
- readonly attribute byte rb;
- attribute octet o;
- readonly attribute octet ro;
- attribute short s;
- readonly attribute short rs;
- attribute unsigned short us;
- readonly attribute unsigned short rus;
- attribute long l;
- readonly attribute long rl;
- attribute unsigned long ul;
- readonly attribute unsigned long rul;
- attribute long long ll;
- readonly attribute long long rll;
- attribute unsigned long long ull;
- readonly attribute unsigned long long rull;
- attribute DOMString str;
- readonly attribute DOMString rstr;
- attribute object obj;
- readonly attribute object robj;
- attribute object _object;
- attribute float f;
- readonly attribute float rf;
- };
-
- interface TestAttrNullable {
- attribute byte? b;
- readonly attribute byte? rb;
- attribute octet? o;
- readonly attribute octet? ro;
- attribute short? s;
- readonly attribute short? rs;
- attribute unsigned short? us;
- readonly attribute unsigned short? rus;
- attribute long? l;
- readonly attribute long? rl;
- attribute unsigned long? ul;
- readonly attribute unsigned long? rul;
- attribute long long? ll;
- readonly attribute long long? rll;
- attribute unsigned long long? ull;
- readonly attribute unsigned long long? rull;
- attribute DOMString? str;
- readonly attribute DOMString? rstr;
- attribute object? obj;
- readonly attribute object? robj;
- attribute object? _object;
- attribute float? f;
- readonly attribute float? rf;
- };
-
- interface TestAttrArray {
- attribute byte[] b;
- readonly attribute byte[] rb;
- attribute octet[] o;
- readonly attribute octet[] ro;
- attribute short[] s;
- readonly attribute short[] rs;
- attribute unsigned short[] us;
- readonly attribute unsigned short[] rus;
- attribute long[] l;
- readonly attribute long[] rl;
- attribute unsigned long[] ul;
- readonly attribute unsigned long[] rul;
- attribute long long[] ll;
- readonly attribute long long[] rll;
- attribute unsigned long long[] ull;
- readonly attribute unsigned long long[] rull;
- attribute DOMString[] str;
- readonly attribute DOMString[] rstr;
- attribute object[] obj;
- readonly attribute object[] robj;
- attribute object[] _object;
- attribute float[] f;
- readonly attribute float[] rf;
- };
-
- interface TestAttrNullableArray {
- attribute byte[]? b;
- readonly attribute byte[]? rb;
- attribute octet[]? o;
- readonly attribute octet[]? ro;
- attribute short[]? s;
- readonly attribute short[]? rs;
- attribute unsigned short[]? us;
- readonly attribute unsigned short[]? rus;
- attribute long[]? l;
- readonly attribute long[]? rl;
- attribute unsigned long[]? ul;
- readonly attribute unsigned long[]? rul;
- attribute long long[]? ll;
- readonly attribute long long[]? rll;
- attribute unsigned long long[]? ull;
- readonly attribute unsigned long long[]? rull;
- attribute DOMString[]? str;
- readonly attribute DOMString[]? rstr;
- attribute object[]? obj;
- readonly attribute object[]? robj;
- attribute object[]? _object;
- attribute float[]? f;
- readonly attribute float[]? rf;
- };
-
- interface TestAttrArrayOfNullableTypes {
- attribute byte?[] b;
- readonly attribute byte?[] rb;
- attribute octet?[] o;
- readonly attribute octet?[] ro;
- attribute short?[] s;
- readonly attribute short?[] rs;
- attribute unsigned short?[] us;
- readonly attribute unsigned short?[] rus;
- attribute long?[] l;
- readonly attribute long?[] rl;
- attribute unsigned long?[] ul;
- readonly attribute unsigned long?[] rul;
- attribute long long?[] ll;
- readonly attribute long long?[] rll;
- attribute unsigned long long?[] ull;
- readonly attribute unsigned long long?[] rull;
- attribute DOMString?[] str;
- readonly attribute DOMString?[] rstr;
- attribute object?[] obj;
- readonly attribute object?[] robj;
- attribute object?[] _object;
- attribute float?[] f;
- readonly attribute float?[] rf;
- };
-
- interface TestAttrNullableArrayOfNullableTypes {
- attribute byte?[]? b;
- readonly attribute byte?[]? rb;
- attribute octet?[]? o;
- readonly attribute octet?[]? ro;
- attribute short?[]? s;
- readonly attribute short?[]? rs;
- attribute unsigned short?[]? us;
- readonly attribute unsigned short?[]? rus;
- attribute long?[]? l;
- readonly attribute long?[]? rl;
- attribute unsigned long?[]? ul;
- readonly attribute unsigned long?[]? rul;
- attribute long long?[]? ll;
- readonly attribute long long?[]? rll;
- attribute unsigned long long?[]? ull;
- readonly attribute unsigned long long?[]? rull;
- attribute DOMString?[]? str;
- readonly attribute DOMString?[]? rstr;
- attribute object?[]? obj;
- readonly attribute object?[]? robj;
- attribute object?[]? _object;
- attribute float?[]? f;
- readonly attribute float?[]? rf;
- };
- """)
-
- results = parser.finish()
-
- def checkAttr(attr, QName, name, type, readonly):
- harness.ok(isinstance(attr, WebIDL.IDLAttribute),
- "Should be an IDLAttribute")
- harness.ok(attr.isAttr(), "Attr is an Attr")
- harness.ok(not attr.isMethod(), "Attr is not an method")
- harness.ok(not attr.isConst(), "Attr is not a const")
- harness.check(attr.identifier.QName(), QName, "Attr has the right QName")
- harness.check(attr.identifier.name, name, "Attr has the right name")
- harness.check(str(attr.type), type, "Attr has the right type")
- harness.check(attr.readonly, readonly, "Attr's readonly state is correct")
-
- harness.ok(True, "TestAttr interface parsed without error.")
- harness.check(len(results), 6, "Should be six productions.")
- iface = results[0]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttr", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttr", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "", name, type % "", readonly)
-
- iface = results[1]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrNullable", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrNullable", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "Nullable", name, type % "OrNull", readonly)
-
- iface = results[2]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrArray", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrArray", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "Array", name, type % "Array", readonly)
-
- iface = results[3]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrNullableArray", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrNullableArray", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "NullableArray", name, type % "ArrayOrNull", readonly)
-
- iface = results[4]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrArrayOfNullableTypes", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrArrayOfNullableTypes", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "ArrayOfNullableTypes", name, type % "OrNullArray", readonly)
-
- iface = results[5]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrNullableArrayOfNullableTypes", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrNullableArrayOfNullableTypes", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "NullableArrayOfNullableTypes", name, type % "OrNullArrayOrNull", readonly)
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A {
- [SetterInfallible] readonly attribute boolean foo;
- };
- """)
- results = parser.finish()
- except Exception, x:
- threw = True
- harness.ok(threw, "Should not allow [SetterInfallible] on readonly attributes")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py b/src/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py
deleted file mode 100644
index fb1b97812bc..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py
+++ /dev/null
@@ -1,67 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface AttrSequenceType {
- attribute sequence<object> foo;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Attribute type must not be a sequence type")
-
- parser.reset()
-
- threw = False
- try:
- parser.parse("""
- interface AttrUnionWithSequenceType {
- attribute (sequence<object> or DOMString) foo;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Attribute type must not be a union with a sequence member type")
-
- parser.reset()
-
- threw = False
- try:
- parser.parse("""
- interface AttrNullableUnionWithSequenceType {
- attribute (sequence<object>? or DOMString) foo;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Attribute type must not be a union with a nullable sequence "
- "member type")
-
- parser.reset()
-
- threw = False
- try:
- parser.parse("""
- interface AttrUnionWithUnionWithSequenceType {
- attribute ((sequence<object> or DOMString) or AttrUnionWithUnionWithSequenceType) foo;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Attribute type must not be a union type with a union member "
- "type that has a sequence member type")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py b/src/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py
deleted file mode 100644
index 631e52eba0b..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface Test {
- attribute long b;
- };
- """);
-
- attr = parser.finish()[0].members[0]
- harness.check(attr.type.filename(), '<builtin>', 'Filename on builtin type')
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_builtins.py b/src/components/script/dom/bindings/codegen/parser/tests/test_builtins.py
deleted file mode 100644
index f8563fc2d9b..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_builtins.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestBuiltins {
- attribute boolean b;
- attribute byte s8;
- attribute octet u8;
- attribute short s16;
- attribute unsigned short u16;
- attribute long s32;
- attribute unsigned long u32;
- attribute long long s64;
- attribute unsigned long long u64;
- attribute DOMTimeStamp ts;
- };
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestBuiltins interface parsed without error.")
- harness.check(len(results), 1, "Should be one production")
- harness.ok(isinstance(results[0], WebIDL.IDLInterface),
- "Should be an IDLInterface")
- iface = results[0]
- harness.check(iface.identifier.QName(), "::TestBuiltins", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestBuiltins", "Interface has the right name")
- harness.check(iface.parent, None, "Interface has no parent")
-
- members = iface.members
- harness.check(len(members), 10, "Should be one production")
-
- names = ["b", "s8", "u8", "s16", "u16", "s32", "u32", "s64", "u64", "ts"]
- types = ["Boolean", "Byte", "Octet", "Short", "UnsignedShort", "Long", "UnsignedLong", "LongLong", "UnsignedLongLong", "UnsignedLongLong"]
- for i in range(10):
- attr = members[i]
- harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
- harness.check(attr.identifier.QName(), "::TestBuiltins::" + names[i], "Attr has correct QName")
- harness.check(attr.identifier.name, names[i], "Attr has correct name")
- harness.check(str(attr.type), types[i], "Attr type is the correct name")
- harness.ok(attr.type.isPrimitive(), "Should be a primitive type")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_callback.py b/src/components/script/dom/bindings/codegen/parser/tests/test_callback.py
deleted file mode 100644
index 267d27dc087..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_callback.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestCallback {
- attribute CallbackType? listener;
- };
-
- callback CallbackType = boolean (unsigned long arg);
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestCallback interface parsed without error.")
- harness.check(len(results), 2, "Should be one production.")
- iface = results[0]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestCallback", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestCallback", "Interface has the right name")
- harness.check(len(iface.members), 1, "Expect %s members" % 1)
-
- attr = iface.members[0]
- harness.ok(isinstance(attr, WebIDL.IDLAttribute),
- "Should be an IDLAttribute")
- harness.ok(attr.isAttr(), "Should be an attribute")
- harness.ok(not attr.isMethod(), "Attr is not an method")
- harness.ok(not attr.isConst(), "Attr is not a const")
- harness.check(attr.identifier.QName(), "::TestCallback::listener", "Attr has the right QName")
- harness.check(attr.identifier.name, "listener", "Attr has the right name")
- t = attr.type
- harness.ok(not isinstance(t, WebIDL.IDLWrapperType), "Attr has the right type")
- harness.ok(isinstance(t, WebIDL.IDLNullableType), "Attr has the right type")
- harness.ok(t.isCallback(), "Attr has the right type")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py b/src/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py
deleted file mode 100644
index 80896ca1edb..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- callback interface TestCallbackInterface {
- attribute boolean bool;
- };
- """)
-
- results = parser.finish()
-
- iface = results[0]
-
- harness.ok(iface.isCallback(), "Interface should be a callback")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestInterface {
- };
- callback interface TestCallbackInterface : TestInterface {
- attribute boolean bool;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow non-callback parent of callback interface")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestInterface : TestCallbackInterface {
- };
- callback interface TestCallbackInterface {
- attribute boolean bool;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow callback parent of non-callback interface")
-
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_const.py b/src/components/script/dom/bindings/codegen/parser/tests/test_const.py
deleted file mode 100644
index 12f411363fb..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_const.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestConsts {
- const byte zero = 0;
- const byte b = -1;
- const octet o = 2;
- const short s = -3;
- const unsigned short us = 0x4;
- const long l = -0X5;
- const unsigned long ul = 6;
- const unsigned long long ull = 7;
- const long long ll = -010;
- const boolean t = true;
- const boolean f = false;
- const boolean? n = null;
- const boolean? nt = true;
- const boolean? nf = false;
- };
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestConsts interface parsed without error.")
- harness.check(len(results), 1, "Should be one production.")
- iface = results[0]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestConsts", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestConsts", "Interface has the right name")
- harness.check(len(iface.members), 14, "Expect 14 members")
-
- consts = iface.members
-
- def checkConst(const, QName, name, type, value):
- harness.ok(isinstance(const, WebIDL.IDLConst),
- "Should be an IDLConst")
- harness.ok(const.isConst(), "Const is a const")
- harness.ok(not const.isAttr(), "Const is not an attr")
- harness.ok(not const.isMethod(), "Const is not a method")
- harness.check(const.identifier.QName(), QName, "Const has the right QName")
- harness.check(const.identifier.name, name, "Const has the right name")
- harness.check(str(const.type), type, "Const has the right type")
- harness.ok(const.type.isPrimitive(), "All consts should be primitive")
- harness.check(str(const.value.type), str(const.type),
- "Const's value has the same type as the type")
- harness.check(const.value.value, value, "Const value has the right value.")
-
- checkConst(consts[0], "::TestConsts::zero", "zero", "Byte", 0)
- checkConst(consts[1], "::TestConsts::b", "b", "Byte", -1)
- checkConst(consts[2], "::TestConsts::o", "o", "Octet", 2)
- checkConst(consts[3], "::TestConsts::s", "s", "Short", -3)
- checkConst(consts[4], "::TestConsts::us", "us", "UnsignedShort", 4)
- checkConst(consts[5], "::TestConsts::l", "l", "Long", -5)
- checkConst(consts[6], "::TestConsts::ul", "ul", "UnsignedLong", 6)
- checkConst(consts[7], "::TestConsts::ull", "ull", "UnsignedLongLong", 7)
- checkConst(consts[8], "::TestConsts::ll", "ll", "LongLong", -8)
- checkConst(consts[9], "::TestConsts::t", "t", "Boolean", True)
- checkConst(consts[10], "::TestConsts::f", "f", "Boolean", False)
- checkConst(consts[11], "::TestConsts::n", "n", "BooleanOrNull", None)
- checkConst(consts[12], "::TestConsts::nt", "nt", "BooleanOrNull", True)
- checkConst(consts[13], "::TestConsts::nf", "nf", "BooleanOrNull", False)
-
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_constructor.py b/src/components/script/dom/bindings/codegen/parser/tests/test_constructor.py
deleted file mode 100644
index 6ec1be1871b..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_constructor.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- def checkArgument(argument, QName, name, type, optional, variadic):
- harness.ok(isinstance(argument, WebIDL.IDLArgument),
- "Should be an IDLArgument")
- harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
- harness.check(argument.identifier.name, name, "Argument has the right name")
- harness.check(str(argument.type), type, "Argument has the right return type")
- harness.check(argument.optional, optional, "Argument has the right optional value")
- harness.check(argument.variadic, variadic, "Argument has the right variadic value")
-
- def checkMethod(method, QName, name, signatures,
- static=False, getter=False, setter=False, creator=False,
- deleter=False, legacycaller=False, stringifier=False):
- harness.ok(isinstance(method, WebIDL.IDLMethod),
- "Should be an IDLMethod")
- harness.ok(method.isMethod(), "Method is a method")
- harness.ok(not method.isAttr(), "Method is not an attr")
- harness.ok(not method.isConst(), "Method is not a const")
- harness.check(method.identifier.QName(), QName, "Method has the right QName")
- harness.check(method.identifier.name, name, "Method has the right name")
- harness.check(method.isStatic(), static, "Method has the correct static value")
- harness.check(method.isGetter(), getter, "Method has the correct getter value")
- harness.check(method.isSetter(), setter, "Method has the correct setter value")
- harness.check(method.isCreator(), creator, "Method has the correct creator value")
- harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
- harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
- harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
- harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
-
- sigpairs = zip(method.signatures(), signatures)
- for (gotSignature, expectedSignature) in sigpairs:
- (gotRetType, gotArgs) = gotSignature
- (expectedRetType, expectedArgs) = expectedSignature
-
- harness.check(str(gotRetType), expectedRetType,
- "Method has the expected return type.")
-
- for i in range(0, len(gotArgs)):
- (QName, name, type, optional, variadic) = expectedArgs[i]
- checkArgument(gotArgs[i], QName, name, type, optional, variadic)
-
- parser.parse("""
- [Constructor]
- interface TestConstructorNoArgs {
- };
-
- [Constructor(DOMString name)]
- interface TestConstructorWithArgs {
- };
-
- [Constructor(object foo), Constructor(boolean bar)]
- interface TestConstructorOverloads {
- };
- """)
- results = parser.finish()
- harness.check(len(results), 3, "Should be two productions")
- harness.ok(isinstance(results[0], WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.ok(isinstance(results[1], WebIDL.IDLInterface),
- "Should be an IDLInterface")
-
- checkMethod(results[0].ctor(), "::TestConstructorNoArgs::constructor",
- "constructor", [("TestConstructorNoArgs (Wrapper)", [])])
- checkMethod(results[1].ctor(), "::TestConstructorWithArgs::constructor",
- "constructor",
- [("TestConstructorWithArgs (Wrapper)",
- [("::TestConstructorWithArgs::constructor::name", "name", "String", False, False)])])
- checkMethod(results[2].ctor(), "::TestConstructorOverloads::constructor",
- "constructor",
- [("TestConstructorOverloads (Wrapper)",
- [("::TestConstructorOverloads::constructor::foo", "foo", "Object", False, False)]),
- ("TestConstructorOverloads (Wrapper)",
- [("::TestConstructorOverloads::constructor::bar", "bar", "Boolean", False, False)])])
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py b/src/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py
deleted file mode 100644
index 192c5f6f97b..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py
+++ /dev/null
@@ -1,28 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- [Constructor, NoInterfaceObject]
- interface TestConstructorNoInterfaceObject {
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- [NoInterfaceObject, Constructor]
- interface TestConstructorNoInterfaceObject {
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py b/src/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py
deleted file mode 100644
index 6249d36fb8f..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface Foo;
- interface Bar;
- interface Foo;
- """);
-
- results = parser.finish()
-
- # There should be no duplicate interfaces in the result.
- expectedNames = sorted(['Foo', 'Bar'])
- actualNames = sorted(map(lambda iface: iface.identifier.name, results))
- harness.check(actualNames, expectedNames, "Parser shouldn't output duplicate names.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py b/src/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py
deleted file mode 100644
index 9ae9eb2b66f..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py
+++ /dev/null
@@ -1,198 +0,0 @@
-def WebIDLTest(parser, harness):
- parser.parse("""
- dictionary Dict2 : Dict1 {
- long child = 5;
- Dict1 aaandAnother;
- };
- dictionary Dict1 {
- long parent;
- double otherParent;
- };
- """)
- results = parser.finish()
-
- dict1 = results[1];
- dict2 = results[0];
-
- harness.check(len(dict1.members), 2, "Dict1 has two members")
- harness.check(len(dict2.members), 2, "Dict2 has four members")
-
- harness.check(dict1.members[0].identifier.name, "otherParent",
- "'o' comes before 'p'")
- harness.check(dict1.members[1].identifier.name, "parent",
- "'o' really comes before 'p'")
- harness.check(dict2.members[0].identifier.name, "aaandAnother",
- "'a' comes before 'c'")
- harness.check(dict2.members[1].identifier.name, "child",
- "'a' really comes before 'c'")
-
- # Now reset our parser
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary Dict {
- long prop = 5;
- long prop;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow name duplication in a dictionary")
-
- # Now reset our parser again
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary Dict1 : Dict2 {
- long prop = 5;
- };
- dictionary Dict2 : Dict3 {
- long prop2;
- };
- dictionary Dict3 {
- double prop;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow name duplication in a dictionary and "
- "its ancestor")
-
- # More reset
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface Iface {};
- dictionary Dict : Iface {
- long prop;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow non-dictionary parents for dictionaries")
-
- # Even more reset
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary A : B {};
- dictionary B : A {};
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow cycles in dictionary inheritance chains")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary A {
- [TreatNullAs=EmptyString] DOMString foo;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow [TreatNullAs] on dictionary members");
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary A {
- [TreatUndefinedAs=EmptyString] DOMString foo;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow [TreatUndefinedAs] on dictionary members");
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary A {
- };
- interface X {
- void doFoo(A arg);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Trailing dictionary arg must be optional")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary A {
- };
- interface X {
- void doFoo(A arg1, optional long arg2);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
-
- parser = parser.reset()
- parser.parse("""
- dictionary A {
- };
- interface X {
- void doFoo(A arg1, long arg2);
- };
- """)
- results = parser.finish()
- harness.ok(True, "Dictionary arg followed by required arg can be required")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary A {
- };
- interface X {
- void doFoo(optional A? arg1);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Dictionary arg must not be nullable")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- dictionary A {
- };
- interface X {
- void doFoo((A or long)? arg1);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Dictionary arg must not be in a nullable union")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py b/src/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
deleted file mode 100644
index 86847800631..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
+++ /dev/null
@@ -1,150 +0,0 @@
-def firstArgType(method):
- return method.signatures()[0][1][0].type
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- dictionary Dict {
- };
- callback interface Foo {
- };
- interface Bar {
- // Bit of a pain to get things that have dictionary types
- void passDict(optional Dict arg);
- void passFoo(Foo arg);
- void passNullableUnion((object? or DOMString) arg);
- void passNullable(Foo? arg);
- };
- """)
- results = parser.finish()
-
- iface = results[2]
- harness.ok(iface.isInterface(), "Should have interface")
- dictMethod = iface.members[0]
- ifaceMethod = iface.members[1]
- nullableUnionMethod = iface.members[2]
- nullableIfaceMethod = iface.members[3]
-
- dictType = firstArgType(dictMethod)
- ifaceType = firstArgType(ifaceMethod)
-
- harness.ok(dictType.isDictionary(), "Should have dictionary type");
- harness.ok(ifaceType.isInterface(), "Should have interface type");
- harness.ok(ifaceType.isCallbackInterface(), "Should have callback interface type");
-
- harness.ok(not dictType.isDistinguishableFrom(ifaceType),
- "Dictionary not distinguishable from callback interface")
- harness.ok(not ifaceType.isDistinguishableFrom(dictType),
- "Callback interface not distinguishable from dictionary")
-
- nullableUnionType = firstArgType(nullableUnionMethod)
- nullableIfaceType = firstArgType(nullableIfaceMethod)
-
- harness.ok(nullableUnionType.isUnion(), "Should have union type");
- harness.ok(nullableIfaceType.isInterface(), "Should have interface type");
- harness.ok(nullableIfaceType.nullable(), "Should have nullable type");
-
- harness.ok(not nullableUnionType.isDistinguishableFrom(nullableIfaceType),
- "Nullable type not distinguishable from union with nullable "
- "member type")
- harness.ok(not nullableIfaceType.isDistinguishableFrom(nullableUnionType),
- "Union with nullable member type not distinguishable from "
- "nullable type")
-
- parser = parser.reset()
- parser.parse("""
- interface TestIface {
- void passKid(Kid arg);
- void passParent(Parent arg);
- void passGrandparent(Grandparent arg);
- void passImplemented(Implemented arg);
- void passImplementedParent(ImplementedParent arg);
- void passUnrelated1(Unrelated1 arg);
- void passUnrelated2(Unrelated2 arg);
- void passArrayBuffer(ArrayBuffer arg);
- void passArrayBuffer(ArrayBufferView arg);
- };
-
- interface Kid : Parent {};
- interface Parent : Grandparent {};
- interface Grandparent {};
- interface Implemented : ImplementedParent {};
- Parent implements Implemented;
- interface ImplementedParent {};
- interface Unrelated1 {};
- interface Unrelated2 {};
- """)
- results = parser.finish()
-
- iface = results[0]
- harness.ok(iface.isInterface(), "Should have interface")
- argTypes = [firstArgType(method) for method in iface.members]
- unrelatedTypes = [firstArgType(method) for method in iface.members[-3:]]
-
- for type1 in argTypes:
- for type2 in argTypes:
- distinguishable = (type1 is not type2 and
- (type1 in unrelatedTypes or
- type2 in unrelatedTypes))
-
- harness.check(type1.isDistinguishableFrom(type2),
- distinguishable,
- "Type %s should %sbe distinguishable from type %s" %
- (type1, "" if distinguishable else "not ", type2))
- harness.check(type2.isDistinguishableFrom(type1),
- distinguishable,
- "Type %s should %sbe distinguishable from type %s" %
- (type2, "" if distinguishable else "not ", type1))
-
- parser = parser.reset()
- parser.parse("""
- interface Dummy {};
- interface TestIface {
- void method(long arg1, TestIface arg2);
- void method(long arg1, long arg2);
- void method(long arg1, Dummy arg2);
- void method(DOMString arg1, DOMString arg2, DOMString arg3);
- };
- """)
- results = parser.finish()
- harness.check(len(results[1].members), 1,
- "Should look like we have one method")
- harness.check(len(results[1].members[0].signatures()), 4,
- "Should have four signatures")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface Dummy {};
- interface TestIface {
- void method(long arg1, TestIface arg2);
- void method(long arg1, long arg2);
- void method(any arg1, Dummy arg2);
- void method(DOMString arg1, DOMString arg2, DOMString arg3);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Should throw when args before the distinguishing arg are not "
- "all the same type")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface Dummy {};
- interface TestIface {
- void method(long arg1, TestIface arg2);
- void method(long arg1, long arg2);
- void method(any arg1, DOMString arg2);
- void method(DOMString arg1, DOMString arg2, DOMString arg3);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should throw when there is no distinguishing index")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_double_null.py b/src/components/script/dom/bindings/codegen/parser/tests/test_double_null.py
deleted file mode 100644
index 700c7eade00..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_double_null.py
+++ /dev/null
@@ -1,14 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface DoubleNull {
- attribute byte?? foo;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py b/src/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py
deleted file mode 100644
index 799f2e0e0ed..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py
+++ /dev/null
@@ -1,84 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface DuplicateQualifiers1 {
- getter getter byte foo(unsigned long index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface DuplicateQualifiers2 {
- setter setter byte foo(unsigned long index, byte value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface DuplicateQualifiers3 {
- creator creator byte foo(unsigned long index, byte value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface DuplicateQualifiers4 {
- deleter deleter byte foo(unsigned long index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface DuplicateQualifiers5 {
- getter deleter getter byte foo(unsigned long index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- results = parser.parse("""
- interface DuplicateQualifiers6 {
- creator setter creator byte foo(unsigned long index, byte value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py b/src/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py
deleted file mode 100644
index ee0079f06da..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py
+++ /dev/null
@@ -1,14 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- try:
- parser.parse("""
- enum TestEmptyEnum {
- };
- """)
-
- harness.ok(False, "Should have thrown!")
- except:
- harness.ok(True, "Parsing TestEmptyEnum enum should fail")
-
- results = parser.finish()
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_enum.py b/src/components/script/dom/bindings/codegen/parser/tests/test_enum.py
deleted file mode 100644
index 69a6932062d..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_enum.py
+++ /dev/null
@@ -1,81 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- enum TestEnum {
- "",
- "foo",
- "bar"
- };
-
- interface TestEnumInterface {
- TestEnum doFoo(boolean arg);
- readonly attribute TestEnum foo;
- };
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestEnumInterfaces interface parsed without error.")
- harness.check(len(results), 2, "Should be one production")
- harness.ok(isinstance(results[0], WebIDL.IDLEnum),
- "Should be an IDLEnum")
- harness.ok(isinstance(results[1], WebIDL.IDLInterface),
- "Should be an IDLInterface")
-
- enum = results[0]
- harness.check(enum.identifier.QName(), "::TestEnum", "Enum has the right QName")
- harness.check(enum.identifier.name, "TestEnum", "Enum has the right name")
- harness.check(enum.values(), ["", "foo", "bar"], "Enum has the right values")
-
- iface = results[1]
-
- harness.check(iface.identifier.QName(), "::TestEnumInterface", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestEnumInterface", "Interface has the right name")
- harness.check(iface.parent, None, "Interface has no parent")
-
- members = iface.members
- harness.check(len(members), 2, "Should be one production")
- harness.ok(isinstance(members[0], WebIDL.IDLMethod),
- "Should be an IDLMethod")
- method = members[0]
- harness.check(method.identifier.QName(), "::TestEnumInterface::doFoo",
- "Method has correct QName")
- harness.check(method.identifier.name, "doFoo", "Method has correct name")
-
- signatures = method.signatures()
- harness.check(len(signatures), 1, "Expect one signature")
-
- (returnType, arguments) = signatures[0]
- harness.check(str(returnType), "TestEnum (Wrapper)", "Method type is the correct name")
- harness.check(len(arguments), 1, "Method has the right number of arguments")
- arg = arguments[0]
- harness.ok(isinstance(arg, WebIDL.IDLArgument), "Should be an IDLArgument")
- harness.check(str(arg.type), "Boolean", "Argument has the right type")
-
- attr = members[1]
- harness.check(attr.identifier.QName(), "::TestEnumInterface::foo",
- "Attr has correct QName")
- harness.check(attr.identifier.name, "foo", "Attr has correct name")
-
- harness.check(str(attr.type), "TestEnum (Wrapper)", "Attr type is the correct name")
-
- # Now reset our parser
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- enum Enum {
- "a",
- "b",
- "c"
- };
- interface TestInterface {
- void foo(optional Enum e = "d");
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow a bogus default value for an enum")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py b/src/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py
deleted file mode 100644
index 51205d209e7..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- try:
- parser.parse("""
- enum TestEnumDuplicateValue {
- "",
- ""
- };
- """)
- harness.ok(False, "Should have thrown!")
- except:
- harness.ok(True, "Enum TestEnumDuplicateValue should throw")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py b/src/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py
deleted file mode 100644
index ca0674aec04..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- # Check that error messages put the '^' in the right place.
-
- threw = False
- input = 'interface ?'
- try:
- parser.parse(input)
- results = parser.finish()
- except WebIDL.WebIDLError, e:
- threw = True
- lines = str(e).split('\n')
-
- harness.check(len(lines), 3, 'Expected number of lines in error message')
- harness.check(lines[1], input, 'Second line shows error')
- harness.check(lines[2], ' ' * (len(input) - 1) + '^',
- 'Correct column pointer in error message')
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py b/src/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py
deleted file mode 100644
index f11222e7a4d..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- # Check that error messages put the '^' in the right place.
-
- threw = False
- input = """\
-// This is a comment.
-interface Foo {
-};
-
-/* This is also a comment. */
-interface ?"""
- try:
- parser.parse(input)
- results = parser.finish()
- except WebIDL.WebIDLError, e:
- threw = True
- lines = str(e).split('\n')
-
- harness.check(len(lines), 3, 'Expected number of lines in error message')
- harness.ok(lines[0].endswith('line 6:10'), 'First line of error should end with "line 6:10", but was "%s".' % lines[0])
- harness.check(lines[1], 'interface ?', 'Second line of error message is the line which caused the error.')
- harness.check(lines[2], ' ' * (len('interface ?') - 1) + '^',
- 'Correct column pointer in error message.')
-
- harness.ok(threw, "Should have thrown.")
-
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py b/src/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py
deleted file mode 100644
index 5c6887331e7..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py
+++ /dev/null
@@ -1,107 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- [Flippety]
- interface TestExtendedAttr {
- [Foopy] attribute byte b;
- };
- """)
-
- results = parser.finish()
-
- parser = parser.reset()
- parser.parse("""
- [Flippety="foo.bar",Floppety=flop]
- interface TestExtendedAttr {
- [Foopy="foo.bar"] attribute byte b;
- };
- """)
-
- results = parser.finish()
-
- parser = parser.reset()
- parser.parse("""
- interface TestLenientThis {
- [LenientThis] attribute byte b;
- };
- """)
-
- results = parser.finish()
- harness.ok(results[0].members[0].hasLenientThis(),
- "Should have a lenient this")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestLenientThis2 {
- [LenientThis=something] attribute byte b;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "[LenientThis] must take no arguments")
-
- parser = parser.reset()
- parser.parse("""
- interface TestClamp {
- void testClamp([Clamp] long foo);
- void testNotClamp(long foo);
- };
- """)
-
- results = parser.finish()
- # Pull out the first argument out of the arglist of the first (and
- # only) signature.
- harness.ok(results[0].members[0].signatures()[0][1][0].clamp,
- "Should be clamped")
- harness.ok(not results[0].members[1].signatures()[0][1][0].clamp,
- "Should not be clamped")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestClamp2 {
- void testClamp([Clamp=something] long foo);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "[Clamp] must take no arguments")
-
- parser = parser.reset()
- parser.parse("""
- interface TestEnforceRange {
- void testEnforceRange([EnforceRange] long foo);
- void testNotEnforceRange(long foo);
- };
- """)
-
- results = parser.finish()
- # Pull out the first argument out of the arglist of the first (and
- # only) signature.
- harness.ok(results[0].members[0].signatures()[0][1][0].enforceRange,
- "Should be enforceRange")
- harness.ok(not results[0].members[1].signatures()[0][1][0].enforceRange,
- "Should not be enforceRange")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestEnforceRange2 {
- void testEnforceRange([EnforceRange=something] long foo);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "[EnforceRange] must take no arguments")
-
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py b/src/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py
deleted file mode 100644
index cac24c832cc..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface ForwardDeclared;
- interface ForwardDeclared;
-
- interface TestForwardDecl {
- attribute ForwardDeclared foo;
- };
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestForwardDeclared interface parsed without error.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_implements.py b/src/components/script/dom/bindings/codegen/parser/tests/test_implements.py
deleted file mode 100644
index 04c47d92abe..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_implements.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Import the WebIDL module, so we can do isinstance checks and whatnot
-import WebIDL
-
-def WebIDLTest(parser, harness):
- # Basic functionality
- threw = False
- try:
- parser.parse("""
- A implements B;
- interface B {
- attribute long x;
- };
- interface A {
- attribute long y;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(not threw, "Should not have thrown on implements statement "
- "before interfaces")
- harness.check(len(results), 3, "We have three statements")
- harness.ok(isinstance(results[1], WebIDL.IDLInterface), "B is an interface")
- harness.check(len(results[1].members), 1, "B has one member")
- A = results[2]
- harness.ok(isinstance(A, WebIDL.IDLInterface), "A is an interface")
- harness.check(len(A.members), 2, "A has two members")
- harness.check(A.members[0].identifier.name, "y", "First member is 'y'")
- harness.check(A.members[1].identifier.name, "x", "Second member is 'x'")
-
- # Duplicated member names not allowed
- threw = False
- try:
- parser.parse("""
- C implements D;
- interface D {
- attribute long x;
- };
- interface C {
- attribute long x;
- };
- """)
- parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown on implemented interface duplicating "
- "a name on base interface")
-
- # Same, but duplicated across implemented interfaces
- threw = False
- try:
- parser.parse("""
- E implements F;
- E implements G;
- interface F {
- attribute long x;
- };
- interface G {
- attribute long x;
- };
- interface E {};
- """)
- parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown on implemented interfaces "
- "duplicating each other's member names")
-
- # Same, but duplicated across indirectly implemented interfaces
- threw = False
- try:
- parser.parse("""
- H implements I;
- H implements J;
- I implements K;
- interface K {
- attribute long x;
- };
- interface L {
- attribute long x;
- };
- interface I {};
- interface J : L {};
- interface H {};
- """)
- parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown on indirectly implemented interfaces "
- "duplicating each other's member names")
-
- # Same, but duplicated across an implemented interface and its parent
- threw = False
- try:
- parser.parse("""
- M implements N;
- interface O {
- attribute long x;
- };
- interface N : O {
- attribute long x;
- };
- interface M {};
- """)
- parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown on implemented interface and its "
- "ancestor duplicating member names")
-
- # Reset the parser so we can actually find things where we expect
- # them in the list
- parser = parser.reset()
-
- # Diamonds should be allowed
- threw = False
- try:
- parser.parse("""
- P implements Q;
- P implements R;
- Q implements S;
- R implements S;
- interface Q {};
- interface R {};
- interface S {
- attribute long x;
- };
- interface P {};
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(not threw, "Diamond inheritance is fine")
- harness.check(results[6].identifier.name, "S", "We should be looking at 'S'")
- harness.check(len(results[6].members), 1, "S should have one member")
- harness.check(results[6].members[0].identifier.name, "x",
- "S's member should be 'x'")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestInterface {
- };
- callback interface TestCallbackInterface {
- };
- TestInterface implements TestCallbackInterface;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Should not allow callback interfaces on the right-hand side "
- "of 'implements'")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestInterface {
- };
- callback interface TestCallbackInterface {
- };
- TestCallbackInterface implements TestInterface;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Should not allow callback interfaces on the left-hand side of "
- "'implements'")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestInterface {
- };
- dictionary Dict {
- };
- Dict implements TestInterface;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Should not allow non-interfaces on the left-hand side "
- "of 'implements'")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface TestInterface {
- };
- dictionary Dict {
- };
- TestInterface implements Dict;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Should not allow non-interfaces on the right-hand side "
- "of 'implements'")
-
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py b/src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py
deleted file mode 100644
index 1f520a28e16..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestIncompleteParent : NotYetDefined {
- void foo();
- };
-
- interface NotYetDefined : EvenHigherOnTheChain {
- };
-
- interface EvenHigherOnTheChain {
- };
- """)
-
- parser.finish()
-
- harness.ok(True, "TestIncompleteParent interface parsed without error.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py b/src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py
deleted file mode 100644
index fdc39604070..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestIncompleteTypes {
- attribute FooInterface attr1;
-
- FooInterface method1(FooInterface arg);
- };
-
- interface FooInterface {
- };
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestIncompleteTypes interface parsed without error.")
- harness.check(len(results), 2, "Should be two productions.")
- iface = results[0]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestIncompleteTypes", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestIncompleteTypes", "Interface has the right name")
- harness.check(len(iface.members), 2, "Expect 2 members")
-
- attr = iface.members[0]
- harness.ok(isinstance(attr, WebIDL.IDLAttribute),
- "Should be an IDLAttribute")
- method = iface.members[1]
- harness.ok(isinstance(method, WebIDL.IDLMethod),
- "Should be an IDLMethod")
-
- harness.check(attr.identifier.QName(), "::TestIncompleteTypes::attr1",
- "Attribute has the right QName")
- harness.check(attr.type.name, "FooInterface",
- "Previously unresolved type has the right name")
-
- harness.check(method.identifier.QName(), "::TestIncompleteTypes::method1",
- "Attribute has the right QName")
- (returnType, args) = method.signatures()[0]
- harness.check(returnType.name, "FooInterface",
- "Previously unresolved type has the right name")
- harness.check(args[0].type.name, "FooInterface",
- "Previously unresolved type has the right name")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_interface.py b/src/components/script/dom/bindings/codegen/parser/tests/test_interface.py
deleted file mode 100644
index 5b07172c636..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_interface.py
+++ /dev/null
@@ -1,188 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("interface Foo { };")
- results = parser.finish()
- harness.ok(True, "Empty interface parsed without error.")
- harness.check(len(results), 1, "Should be one production")
- harness.ok(isinstance(results[0], WebIDL.IDLInterface),
- "Should be an IDLInterface")
- iface = results[0]
- harness.check(iface.identifier.QName(), "::Foo", "Interface has the right QName")
- harness.check(iface.identifier.name, "Foo", "Interface has the right name")
- harness.check(iface.parent, None, "Interface has no parent")
-
- parser.parse("interface Bar : Foo { };")
- results = parser.finish()
- harness.ok(True, "Empty interface parsed without error.")
- harness.check(len(results), 2, "Should be two productions")
- harness.ok(isinstance(results[1], WebIDL.IDLInterface),
- "Should be an IDLInterface")
- iface = results[1]
- harness.check(iface.identifier.QName(), "::Bar", "Interface has the right QName")
- harness.check(iface.identifier.name, "Bar", "Interface has the right name")
- harness.ok(isinstance(iface.parent, WebIDL.IDLInterface),
- "Interface has a parent")
-
- parser = parser.reset()
- parser.parse("""
- interface QNameBase {
- attribute long foo;
- };
-
- interface QNameDerived : QNameBase {
- attribute long long foo;
- attribute byte bar;
- };
- """)
- results = parser.finish()
- harness.check(len(results), 2, "Should be two productions")
- harness.ok(isinstance(results[0], WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.ok(isinstance(results[1], WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(results[1].parent, results[0], "Inheritance chain is right")
- harness.check(len(results[0].members), 1, "Expect 1 productions")
- harness.check(len(results[1].members), 2, "Expect 2 productions")
- base = results[0]
- derived = results[1]
- harness.check(base.members[0].identifier.QName(), "::QNameBase::foo",
- "Member has the right QName")
- harness.check(derived.members[0].identifier.QName(), "::QNameDerived::foo",
- "Member has the right QName")
- harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar",
- "Member has the right QName")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A : B {};
- interface B : A {};
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow cycles in interface inheritance chains")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A : C {};
- interface C : B {};
- interface B : A {};
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow indirect cycles in interface inheritance chains")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A {};
- interface B {};
- A implements B;
- B implements A;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow cycles via implements")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A {};
- interface C {};
- interface B {};
- A implements C;
- C implements B;
- B implements A;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow indirect cycles via implements")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A : B {};
- interface B {};
- B implements A;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow inheriting from an interface that implements us")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A : B {};
- interface B {};
- interface C {};
- B implements C;
- C implements A;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow inheriting from an interface that indirectly implements us")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A : B {};
- interface B : C {};
- interface C {};
- C implements A;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow indirectly inheriting from an interface that implements us")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A : B {};
- interface B : C {};
- interface C {};
- interface D {};
- C implements D;
- D implements A;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow indirectly inheriting from an interface that indirectly implements us")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A;
- interface B : A {};
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should not allow inheriting from an interface that is only forward declared")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py b/src/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py
deleted file mode 100644
index db944e7aaf7..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py
+++ /dev/null
@@ -1,15 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface IdentifierConflict {
- const byte thing1 = 1;
- const unsigned long thing1 = 1;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py b/src/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py
deleted file mode 100644
index 1a73fb917ed..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py
+++ /dev/null
@@ -1,60 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface IdentifierConflictAcrossMembers1 {
- const byte thing1 = 1;
- readonly attribute long thing1;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface IdentifierConflictAcrossMembers2 {
- readonly attribute long thing1;
- const byte thing1 = 1;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface IdentifierConflictAcrossMembers3 {
- getter boolean thing1(DOMString name);
- readonly attribute long thing1;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface IdentifierConflictAcrossMembers1 {
- const byte thing1 = 1;
- long thing1();
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_method.py b/src/components/script/dom/bindings/codegen/parser/tests/test_method.py
deleted file mode 100644
index 40b2d2cf8b9..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_method.py
+++ /dev/null
@@ -1,145 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestMethods {
- void basic();
- static void basicStatic();
- void basicWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
- boolean basicBoolean();
- static boolean basicStaticBoolean();
- boolean basicBooleanWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
- void optionalArg(optional byte? arg1, optional sequence<byte> arg2);
- void variadicArg(byte?... arg1);
- void crazyTypes(sequence<long?[]>? arg1, boolean?[][]? arg2);
- object getObject();
- void setObject(object arg1);
- void setAny(any arg1);
- float doFloats(float arg1);
- };
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestMethods interface parsed without error.")
- harness.check(len(results), 1, "Should be one production.")
- iface = results[0]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestMethods", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestMethods", "Interface has the right name")
- harness.check(len(iface.members), 13, "Expect 13 members")
-
- methods = iface.members
-
- def checkArgument(argument, QName, name, type, optional, variadic):
- harness.ok(isinstance(argument, WebIDL.IDLArgument),
- "Should be an IDLArgument")
- harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
- harness.check(argument.identifier.name, name, "Argument has the right name")
- harness.check(str(argument.type), type, "Argument has the right return type")
- harness.check(argument.optional, optional, "Argument has the right optional value")
- harness.check(argument.variadic, variadic, "Argument has the right variadic value")
-
- def checkMethod(method, QName, name, signatures,
- static=False, getter=False, setter=False, creator=False,
- deleter=False, legacycaller=False, stringifier=False):
- harness.ok(isinstance(method, WebIDL.IDLMethod),
- "Should be an IDLMethod")
- harness.ok(method.isMethod(), "Method is a method")
- harness.ok(not method.isAttr(), "Method is not an attr")
- harness.ok(not method.isConst(), "Method is not a const")
- harness.check(method.identifier.QName(), QName, "Method has the right QName")
- harness.check(method.identifier.name, name, "Method has the right name")
- harness.check(method.isStatic(), static, "Method has the correct static value")
- harness.check(method.isGetter(), getter, "Method has the correct getter value")
- harness.check(method.isSetter(), setter, "Method has the correct setter value")
- harness.check(method.isCreator(), creator, "Method has the correct creator value")
- harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
- harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
- harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
- harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
-
- sigpairs = zip(method.signatures(), signatures)
- for (gotSignature, expectedSignature) in sigpairs:
- (gotRetType, gotArgs) = gotSignature
- (expectedRetType, expectedArgs) = expectedSignature
-
- harness.check(str(gotRetType), expectedRetType,
- "Method has the expected return type.")
-
- for i in range(0, len(gotArgs)):
- (QName, name, type, optional, variadic) = expectedArgs[i]
- checkArgument(gotArgs[i], QName, name, type, optional, variadic)
-
- checkMethod(methods[0], "::TestMethods::basic", "basic", [("Void", [])])
- checkMethod(methods[1], "::TestMethods::basicStatic", "basicStatic",
- [("Void", [])], static=True)
- checkMethod(methods[2], "::TestMethods::basicWithSimpleArgs",
- "basicWithSimpleArgs",
- [("Void",
- [("::TestMethods::basicWithSimpleArgs::arg1", "arg1", "Boolean", False, False),
- ("::TestMethods::basicWithSimpleArgs::arg2", "arg2", "Byte", False, False),
- ("::TestMethods::basicWithSimpleArgs::arg3", "arg3", "UnsignedLong", False, False)])])
- checkMethod(methods[3], "::TestMethods::basicBoolean", "basicBoolean", [("Boolean", [])])
- checkMethod(methods[4], "::TestMethods::basicStaticBoolean", "basicStaticBoolean", [("Boolean", [])], static=True)
- checkMethod(methods[5], "::TestMethods::basicBooleanWithSimpleArgs",
- "basicBooleanWithSimpleArgs",
- [("Boolean",
- [("::TestMethods::basicBooleanWithSimpleArgs::arg1", "arg1", "Boolean", False, False),
- ("::TestMethods::basicBooleanWithSimpleArgs::arg2", "arg2", "Byte", False, False),
- ("::TestMethods::basicBooleanWithSimpleArgs::arg3", "arg3", "UnsignedLong", False, False)])])
- checkMethod(methods[6], "::TestMethods::optionalArg",
- "optionalArg",
- [("Void",
- [("::TestMethods::optionalArg::arg1", "arg1", "ByteOrNull", True, False),
- ("::TestMethods::optionalArg::arg2", "arg2", "ByteSequence", True, False)])])
- checkMethod(methods[7], "::TestMethods::variadicArg",
- "variadicArg",
- [("Void",
- [("::TestMethods::variadicArg::arg1", "arg1", "ByteOrNull", True, True)])])
- checkMethod(methods[8], "::TestMethods::crazyTypes",
- "crazyTypes",
- [("Void",
- [("::TestMethods::crazyTypes::arg1", "arg1", "LongOrNullArraySequenceOrNull", False, False),
- ("::TestMethods::crazyTypes::arg2", "arg2", "BooleanOrNullArrayArrayOrNull", False, False)])])
- checkMethod(methods[9], "::TestMethods::getObject",
- "getObject", [("Object", [])])
- checkMethod(methods[10], "::TestMethods::setObject",
- "setObject",
- [("Void",
- [("::TestMethods::setObject::arg1", "arg1", "Object", False, False)])])
- checkMethod(methods[11], "::TestMethods::setAny",
- "setAny",
- [("Void",
- [("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])])
- checkMethod(methods[12], "::TestMethods::doFloats",
- "doFloats",
- [("Float",
- [("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])])
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A {
- [GetterInfallible] void foo();
- };
- """)
- results = parser.finish()
- except Exception, x:
- threw = True
- harness.ok(threw, "Should not allow [GetterInfallible] on methods")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface A {
- [SetterInfallible] void foo();
- };
- """)
- results = parser.finish()
- except Exception, x:
- threw = True
- harness.ok(threw, "Should not allow [SetterInfallible] on methods")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py b/src/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py
deleted file mode 100644
index 3366b9fbbbd..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py
+++ /dev/null
@@ -1,126 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestNullableEquivalency1 {
- attribute long a;
- attribute long? b;
- };
-
- interface TestNullableEquivalency2 {
- attribute ArrayBuffer a;
- attribute ArrayBuffer? b;
- };
-
- /* Can't have dictionary-valued attributes, so can't test that here */
-
- enum TestNullableEquivalency4Enum {
- "Foo",
- "Bar"
- };
-
- interface TestNullableEquivalency4 {
- attribute TestNullableEquivalency4Enum a;
- attribute TestNullableEquivalency4Enum? b;
- };
-
- interface TestNullableEquivalency5 {
- attribute TestNullableEquivalency4 a;
- attribute TestNullableEquivalency4? b;
- };
-
- interface TestNullableEquivalency6 {
- attribute boolean a;
- attribute boolean? b;
- };
-
- interface TestNullableEquivalency7 {
- attribute DOMString a;
- attribute DOMString? b;
- };
-
- /* Not implemented. */
- /*interface TestNullableEquivalency8 {
- attribute float a;
- attribute float? b;
- };*/
-
- interface TestNullableEquivalency8 {
- attribute double a;
- attribute double? b;
- };
-
- interface TestNullableEquivalency9 {
- attribute object a;
- attribute object? b;
- };
-
- interface TestNullableEquivalency10 {
- attribute double[] a;
- attribute double[]? b;
- };
-
- interface TestNullableEquivalency11 {
- attribute TestNullableEquivalency9[] a;
- attribute TestNullableEquivalency9[]? b;
- };
- """)
-
- for decl in parser.finish():
- if decl.isInterface():
- checkEquivalent(decl, harness)
-
-def checkEquivalent(iface, harness):
- type1 = iface.members[0].type
- type2 = iface.members[1].type
-
- harness.check(type1.nullable(), False, 'attr1 should not be nullable')
- harness.check(type2.nullable(), True, 'attr2 should be nullable')
-
- # We don't know about type1, but type2, the nullable type, definitely
- # shouldn't be builtin.
- harness.check(type2.builtin, False, 'attr2 should not be builtin')
-
- # Ensure that all attributes of type2 match those in type1, except for:
- # - names on an ignore list,
- # - names beginning with '_',
- # - functions which throw when called with no args, and
- # - class-level non-callables ("static variables").
- #
- # Yes, this is an ugly, fragile hack. But it finds bugs...
- for attr in dir(type1):
- if attr.startswith('_') or \
- attr in ['nullable', 'builtin', 'filename', 'location',
- 'inner', 'QName'] or \
- (hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
- continue
-
- a1 = getattr(type1, attr)
-
- if callable(a1):
- try:
- v1 = a1()
- except:
- # Can't call a1 with no args, so skip this attriute.
- continue
-
- try:
- a2 = getattr(type2, attr)
- except:
- harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
- continue
-
- if not callable(a2):
- harness.ok(False, "%s attribute on type %s in %s wasn't callable" % (attr, type2, iface))
- continue
-
- v2 = a2()
- harness.check(v2, v1, '%s method return value' % attr)
- else:
- try:
- a2 = getattr(type2, attr)
- except:
- harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
- continue
-
- harness.check(a2, a1, '%s attribute should match' % attr)
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py b/src/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py
deleted file mode 100644
index 961ff825e9f..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py
+++ /dev/null
@@ -1,14 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface NullableVoid {
- void? foo();
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py b/src/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py
deleted file mode 100644
index 1dcdc7fb8a5..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py
+++ /dev/null
@@ -1,14 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface OptionalConstraints1 {
- void foo(optional byte arg1, byte arg2);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_overload.py b/src/components/script/dom/bindings/codegen/parser/tests/test_overload.py
deleted file mode 100644
index 59d9be54e53..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_overload.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface TestOverloads {
- void basic();
- void basic(long arg1);
- boolean abitharder(TestOverloads foo);
- boolean abitharder(boolean foo);
- void abitharder(ArrayBuffer? foo);
- };
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestOverloads interface parsed without error.")
- harness.check(len(results), 1, "Should be one production.")
- iface = results[0]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name")
- harness.check(len(iface.members), 2, "Expect %s members" % 2)
-
- member = iface.members[0]
- harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
- harness.check(member.identifier.name, "basic", "Method has the right name")
- harness.check(member.hasOverloads(), True, "Method has overloads")
-
- signatures = member.signatures()
- harness.check(len(signatures), 2, "Method should have 2 signatures")
-
- (retval, argumentSet) = signatures[0]
-
- harness.check(str(retval), "Void", "Expect a void retval")
- harness.check(len(argumentSet), 0, "Expect an empty argument set")
-
- (retval, argumentSet) = signatures[1]
- harness.check(str(retval), "Void", "Expect a void retval")
- harness.check(len(argumentSet), 1, "Expect an argument set with one argument")
-
- argument = argumentSet[0]
- harness.ok(isinstance(argument, WebIDL.IDLArgument),
- "Should be an IDLArgument")
- harness.check(argument.identifier.QName(), "::TestOverloads::basic::arg1", "Argument has the right QName")
- harness.check(argument.identifier.name, "arg1", "Argument has the right name")
- harness.check(str(argument.type), "Long", "Argument has the right type")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_sanity.py b/src/components/script/dom/bindings/codegen/parser/tests/test_sanity.py
deleted file mode 100644
index d3184c00731..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_sanity.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def WebIDLTest(parser, harness):
- parser.parse("")
- parser.finish()
- harness.ok(True, "Parsing nothing doesn't throw.")
- parser.parse("interface Foo {};")
- parser.finish()
- harness.ok(True, "Parsing a silly interface doesn't throw.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py b/src/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py
deleted file mode 100644
index 5ea1743d36a..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py
+++ /dev/null
@@ -1,294 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch1 {
- getter long long foo(long index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch2 {
- getter void foo(unsigned long index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch3 {
- getter boolean foo(unsigned long index, boolean extraArg);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch4 {
- getter boolean foo(unsigned long... index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch5 {
- getter boolean foo(optional unsigned long index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch6 {
- getter boolean foo();
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch7 {
- deleter long long foo(long index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch9 {
- deleter boolean foo(unsigned long index, boolean extraArg);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch10 {
- deleter boolean foo(unsigned long... index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch11 {
- deleter boolean foo(optional unsigned long index);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch12 {
- deleter boolean foo();
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch13 {
- setter long long foo(long index, long long value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch15 {
- setter boolean foo(unsigned long index, boolean value, long long extraArg);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch16 {
- setter boolean foo(unsigned long index, boolean... value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch17 {
- setter boolean foo(unsigned long index, optional boolean value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch18 {
- setter boolean foo();
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch20 {
- creator long long foo(long index, long long value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch22 {
- creator boolean foo(unsigned long index, boolean value, long long extraArg);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch23 {
- creator boolean foo(unsigned long index, boolean... value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch24 {
- creator boolean foo(unsigned long index, optional boolean value);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodSignatureMismatch25 {
- creator boolean foo();
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py b/src/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py
deleted file mode 100644
index 695cfe4f250..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py
+++ /dev/null
@@ -1,73 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface SpecialMethods {
- getter long long (unsigned long index);
- setter long long (unsigned long index, long long value);
- creator long long (unsigned long index, long long value);
- deleter long long (unsigned long index);
- getter boolean (DOMString name);
- setter boolean (DOMString name, boolean value);
- creator boolean (DOMString name, boolean value);
- deleter boolean (DOMString name);
- };
-
- interface SpecialMethodsCombination {
- getter deleter long long (unsigned long index);
- setter creator long long (unsigned long index, long long value);
- getter deleter boolean (DOMString name);
- setter creator boolean (DOMString name, boolean value);
- };
- """)
-
- results = parser.finish()
-
- def checkMethod(method, QName, name,
- static=False, getter=False, setter=False, creator=False,
- deleter=False, legacycaller=False, stringifier=False):
- harness.ok(isinstance(method, WebIDL.IDLMethod),
- "Should be an IDLMethod")
- harness.check(method.identifier.QName(), QName, "Method has the right QName")
- harness.check(method.identifier.name, name, "Method has the right name")
- harness.check(method.isStatic(), static, "Method has the correct static value")
- harness.check(method.isGetter(), getter, "Method has the correct getter value")
- harness.check(method.isSetter(), setter, "Method has the correct setter value")
- harness.check(method.isCreator(), creator, "Method has the correct creator value")
- harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
- harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
- harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
-
- harness.check(len(results), 2, "Expect 2 interfaces")
-
- iface = results[0]
- harness.check(len(iface.members), 8, "Expect 8 members")
-
- checkMethod(iface.members[0], "::SpecialMethods::__indexedgetter", "__indexedgetter",
- getter=True)
- checkMethod(iface.members[1], "::SpecialMethods::__indexedsetter", "__indexedsetter",
- setter=True)
- checkMethod(iface.members[2], "::SpecialMethods::__indexedcreator", "__indexedcreator",
- creator=True)
- checkMethod(iface.members[3], "::SpecialMethods::__indexeddeleter", "__indexeddeleter",
- deleter=True)
- checkMethod(iface.members[4], "::SpecialMethods::__namedgetter", "__namedgetter",
- getter=True)
- checkMethod(iface.members[5], "::SpecialMethods::__namedsetter", "__namedsetter",
- setter=True)
- checkMethod(iface.members[6], "::SpecialMethods::__namedcreator", "__namedcreator",
- creator=True)
- checkMethod(iface.members[7], "::SpecialMethods::__nameddeleter", "__nameddeleter",
- deleter=True)
-
- iface = results[1]
- harness.check(len(iface.members), 4, "Expect 4 members")
-
- checkMethod(iface.members[0], "::SpecialMethodsCombination::__indexedgetterdeleter",
- "__indexedgetterdeleter", getter=True, deleter=True)
- checkMethod(iface.members[1], "::SpecialMethodsCombination::__indexedsettercreator",
- "__indexedsettercreator", setter=True, creator=True)
- checkMethod(iface.members[2], "::SpecialMethodsCombination::__namedgetterdeleter",
- "__namedgetterdeleter", getter=True, deleter=True)
- checkMethod(iface.members[3], "::SpecialMethodsCombination::__namedsettercreator",
- "__namedsettercreator", setter=True, creator=True)
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py b/src/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py
deleted file mode 100644
index 42e2c5bb71b..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py
+++ /dev/null
@@ -1,62 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodUniqueness1 {
- getter deleter boolean (DOMString name);
- getter boolean (DOMString name);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodUniqueness1 {
- deleter boolean (DOMString name);
- getter deleter boolean (DOMString name);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodUniqueness1 {
- setter creator boolean (DOMString name);
- creator boolean (DOMString name);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- parser.parse("""
- interface SpecialMethodUniqueness1 {
- setter boolean (DOMString name);
- creator setter boolean (DOMString name);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py b/src/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py
deleted file mode 100644
index 3d0e5ca479f..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- callback Function = any(any... arguments);
-
- interface TestTreatNonCallableAsNull1 {
- [TreatNonCallableAsNull] attribute Function? onfoo;
- attribute Function? onbar;
- };
- """)
-
- results = parser.finish()
-
- iface = results[1]
- attr = iface.members[0]
- harness.check(attr.type.treatNonCallableAsNull(), True, "Got the expected value")
- attr = iface.members[1]
- harness.check(attr.type.treatNonCallableAsNull(), False, "Got the expected value")
-
- parser = parser.reset()
-
- threw = False
- try:
- parser.parse("""
- callback Function = any(any... arguments);
-
- interface TestTreatNonCallableAsNull2 {
- [TreatNonCallableAsNull] attribute Function onfoo;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- parser = parser.reset()
-
- threw = False
- try:
- parser.parse("""
- callback Function = any(any... arguments);
-
- [TreatNonCallableAsNull]
- interface TestTreatNonCallableAsNull3 {
- attribute Function onfoo;
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_typedef.py b/src/components/script/dom/bindings/codegen/parser/tests/test_typedef.py
deleted file mode 100644
index 9d2f3b3c2ce..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_typedef.py
+++ /dev/null
@@ -1,76 +0,0 @@
-def WebIDLTest(parser, harness):
- parser.parse("""
- typedef long mylong;
- typedef long? mynullablelong;
- interface Foo {
- const mylong X = 5;
- const mynullablelong Y = 7;
- const mynullablelong Z = null;
- void foo(mylong arg);
- };
- """)
-
- results = parser.finish()
-
- harness.check(results[2].members[1].type.name, "Long",
- "Should expand typedefs")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- typedef long? mynullablelong;
- interface Foo {
- void foo(mynullablelong? Y);
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown on nullable inside nullable arg.")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- typedef long? mynullablelong;
- interface Foo {
- const mynullablelong? X = 5;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown on nullable inside nullable const.")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- interface Foo {
- const mynullablelong? X = 5;
- };
- typedef long? mynullablelong;
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Should have thrown on nullable inside nullable const typedef "
- "after interface.")
-
- parser = parser.reset()
- parser.parse("""
- interface Foo {
- const mylong X = 5;
- };
- typedef long mylong;
- """)
-
- results = parser.finish()
-
- harness.check(results[0].members[0].type.name, "Long",
- "Should expand typedefs that come before interface")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_union.py b/src/components/script/dom/bindings/codegen/parser/tests/test_union.py
deleted file mode 100644
index 68c2bcade8c..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_union.py
+++ /dev/null
@@ -1,169 +0,0 @@
-import WebIDL
-import itertools
-import string
-
-# We'd like to use itertools.chain but it's 2.6 or higher.
-def chain(*iterables):
- # chain('ABC', 'DEF') --> A B C D E F
- for it in iterables:
- for element in it:
- yield element
-
-# We'd like to use itertools.combinations but it's 2.6 or higher.
-def combinations(iterable, r):
- # combinations('ABCD', 2) --> AB AC AD BC BD CD
- # combinations(range(4), 3) --> 012 013 023 123
- pool = tuple(iterable)
- n = len(pool)
- if r > n:
- return
- indices = range(r)
- yield tuple(pool[i] for i in indices)
- while True:
- for i in reversed(range(r)):
- if indices[i] != i + n - r:
- break
- else:
- return
- indices[i] += 1
- for j in range(i+1, r):
- indices[j] = indices[j-1] + 1
- yield tuple(pool[i] for i in indices)
-
-# We'd like to use itertools.combinations_with_replacement but it's 2.7 or
-# higher.
-def combinations_with_replacement(iterable, r):
- # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
- pool = tuple(iterable)
- n = len(pool)
- if not n and r:
- return
- indices = [0] * r
- yield tuple(pool[i] for i in indices)
- while True:
- for i in reversed(range(r)):
- if indices[i] != n - 1:
- break
- else:
- return
- indices[i:] = [indices[i] + 1] * (r - i)
- yield tuple(pool[i] for i in indices)
-
-def WebIDLTest(parser, harness):
- types = ["float",
- "double",
- "short",
- "unsigned short",
- "long",
- "unsigned long",
- "long long",
- "unsigned long long",
- "boolean",
- "byte",
- "octet",
- "DOMString",
- #"sequence<float>",
- "object",
- "ArrayBuffer",
- #"Date",
- "TestInterface1",
- "TestInterface2"]
-
- testPre = """
- interface TestInterface1 {
- };
- interface TestInterface2 {
- };
- """
-
- interface = testPre + """
- interface PrepareForTest {
- """
- for (i, type) in enumerate(types):
- interface += string.Template("""
- readonly attribute ${type} attr${i};
- """).substitute(i=i, type=type)
- interface += """
- };
- """
-
- parser.parse(interface)
- results = parser.finish()
-
- iface = results[2]
-
- parser = parser.reset()
-
- def typesAreDistinguishable(t):
- return all(u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
- def typesAreNotDistinguishable(t):
- return any(not u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
- def unionTypeName(t):
- if len(t) > 2:
- t[0:2] = [unionTypeName(t[0:2])]
- return "(" + " or ".join(t) + ")"
-
- # typeCombinations is an iterable of tuples containing the name of the type
- # as a string and the parsed IDL type.
- def unionTypes(typeCombinations, predicate):
- for c in typeCombinations:
- if predicate(t[1] for t in c):
- yield unionTypeName([t[0] for t in c])
-
- # We limit invalid union types with a union member type to the subset of 3
- # types with one invalid combination.
- # typeCombinations is an iterable of tuples containing the name of the type
- # as a string and the parsed IDL type.
- def invalidUnionWithUnion(typeCombinations):
- for c in typeCombinations:
- if (typesAreNotDistinguishable((c[0][1], c[1][1])) and
- typesAreDistinguishable((c[1][1], c[2][1])) and
- typesAreDistinguishable((c[0][1], c[2][1]))):
- yield unionTypeName([t[0] for t in c])
-
- # Create a list of tuples containing the name of the type as a string and
- # the parsed IDL type.
- types = zip(types, (a.type for a in iface.members))
-
- validUnionTypes = chain(unionTypes(combinations(types, 2), typesAreDistinguishable),
- unionTypes(combinations(types, 3), typesAreDistinguishable))
- invalidUnionTypes = chain(unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable),
- invalidUnionWithUnion(combinations(types, 3)))
- interface = testPre + """
- interface TestUnion {
- """
- for (i, type) in enumerate(validUnionTypes):
- interface += string.Template("""
- void method${i}(${type} arg);
- ${type} returnMethod${i}();
- attribute ${type} attr${i};
- void arrayMethod${i}(${type}[] arg);
- ${type}[] arrayReturnMethod${i}();
- attribute ${type}[] arrayAttr${i};
- void optionalMethod${i}(${type}? arg);
- """).substitute(i=i, type=type)
- interface += """
- };
- """
- parser.parse(interface)
- results = parser.finish()
-
- parser = parser.reset()
-
- for invalid in invalidUnionTypes:
- interface = testPre + string.Template("""
- interface TestUnion {
- void method(${type} arg);
- };
- """).substitute(type=invalid)
-
- threw = False
- try:
- parser.parse(interface)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- parser = parser.reset()
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_union_any.py b/src/components/script/dom/bindings/codegen/parser/tests/test_union_any.py
deleted file mode 100644
index e34cadab470..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_union_any.py
+++ /dev/null
@@ -1,14 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface AnyNotInUnion {
- void foo((any or DOMString) arg);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py b/src/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py
deleted file mode 100644
index 08430a94a2e..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py
+++ /dev/null
@@ -1,53 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- interface OneNullableInUnion {
- void foo((object? or DOMString?) arg);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "Two nullable member types of a union should have thrown.")
-
- parser.reset()
- threw = False
-
- try:
- parser.parse("""
- interface NullableInNullableUnion {
- void foo((object? or DOMString)? arg);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "A nullable union type with a nullable member type should have "
- "thrown.")
-
- parser.reset()
- threw = False
-
- try:
- parser.parse("""
- interface NullableInUnionNullableUnionHelper {
- };
- interface NullableInUnionNullableUnion {
- void foo(((object? or DOMString) or NullableInUnionNullableUnionHelper)? arg);
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw,
- "A nullable union type with a nullable member type should have "
- "thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py b/src/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py
deleted file mode 100644
index d9a78db2043..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- callback TestVariadicCallback = any(any... arguments);
- """)
-
- results = parser.finish()
-
- harness.ok(True, "TestVariadicCallback callback parsed without error.")
diff --git a/src/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py b/src/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py
deleted file mode 100644
index 9cba22c5842..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py
+++ /dev/null
@@ -1,39 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- results = parser.parse("""
- interface VariadicConstraints1 {
- void foo(byte... arg1, byte arg2);
- };
- """)
-
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- results = parser.parse("""
- interface VariadicConstraints2 {
- void foo(byte... arg1, optional byte arg2);
- };
- """)
-
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- threw = False
- try:
- results = parser.parse("""
- interface VariadicConstraints3 {
- void foo(optional byte... arg1);
- };
- """)
-
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
diff --git a/src/components/script/dom/bindings/codegen/parser/update.sh b/src/components/script/dom/bindings/codegen/parser/update.sh
deleted file mode 100755
index 5dd513812e1..00000000000
--- a/src/components/script/dom/bindings/codegen/parser/update.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-wget https://mxr.mozilla.org/mozilla-central/source/dom/bindings/parser/WebIDL.py?raw=1 -O WebIDL.py
-patch < external.patch
-patch < module.patch
diff --git a/src/components/script/dom/bindings/codegen/ply/COPYING b/src/components/script/dom/bindings/codegen/ply/COPYING
deleted file mode 100644
index 3b107de4508..00000000000
--- a/src/components/script/dom/bindings/codegen/ply/COPYING
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (C) 2001-2009,
-David M. Beazley (Dabeaz LLC)
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-* Neither the name of the David Beazley or Dabeaz LLC may be used to
- endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/components/script/dom/bindings/codegen/ply/README b/src/components/script/dom/bindings/codegen/ply/README
deleted file mode 100644
index 2459c490197..00000000000
--- a/src/components/script/dom/bindings/codegen/ply/README
+++ /dev/null
@@ -1,9 +0,0 @@
-David Beazley's PLY (Python Lex-Yacc)
-http://www.dabeaz.com/ply/
-
-Licensed under BSD.
-
-This directory contains just the code and license from PLY version 3.3;
-the full distribution (see the URL) also contains examples, tests,
-documentation, and a longer README.
-
diff --git a/src/components/script/dom/bindings/codegen/ply/ply/__init__.py b/src/components/script/dom/bindings/codegen/ply/ply/__init__.py
deleted file mode 100644
index 853a985542b..00000000000
--- a/src/components/script/dom/bindings/codegen/ply/ply/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# PLY package
-# Author: David Beazley (dave@dabeaz.com)
-
-__all__ = ['lex','yacc']
diff --git a/src/components/script/dom/bindings/codegen/ply/ply/lex.py b/src/components/script/dom/bindings/codegen/ply/ply/lex.py
deleted file mode 100644
index 267ec100fc2..00000000000
--- a/src/components/script/dom/bindings/codegen/ply/ply/lex.py
+++ /dev/null
@@ -1,1058 +0,0 @@
-# -----------------------------------------------------------------------------
-# ply: lex.py
-#
-# Copyright (C) 2001-2009,
-# David M. Beazley (Dabeaz LLC)
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of the David Beazley or Dabeaz LLC may be used to
-# endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# -----------------------------------------------------------------------------
-
-__version__ = "3.3"
-__tabversion__ = "3.2" # Version of table file used
-
-import re, sys, types, copy, os
-
-# This tuple contains known string types
-try:
- # Python 2.6
- StringTypes = (types.StringType, types.UnicodeType)
-except AttributeError:
- # Python 3.0
- StringTypes = (str, bytes)
-
-# Extract the code attribute of a function. Different implementations
-# are for Python 2/3 compatibility.
-
-if sys.version_info[0] < 3:
- def func_code(f):
- return f.func_code
-else:
- def func_code(f):
- return f.__code__
-
-# This regular expression is used to match valid token names
-_is_identifier = re.compile(r'^[a-zA-Z0-9_]+$')
-
-# Exception thrown when invalid token encountered and no default error
-# handler is defined.
-
-class LexError(Exception):
- def __init__(self,message,s):
- self.args = (message,)
- self.text = s
-
-# Token class. This class is used to represent the tokens produced.
-class LexToken(object):
- def __str__(self):
- return "LexToken(%s,%r,%d,%d)" % (self.type,self.value,self.lineno,self.lexpos)
- def __repr__(self):
- return str(self)
-
-# This object is a stand-in for a logging object created by the
-# logging module.
-
-class PlyLogger(object):
- def __init__(self,f):
- self.f = f
- def critical(self,msg,*args,**kwargs):
- self.f.write((msg % args) + "\n")
-
- def warning(self,msg,*args,**kwargs):
- self.f.write("WARNING: "+ (msg % args) + "\n")
-
- def error(self,msg,*args,**kwargs):
- self.f.write("ERROR: " + (msg % args) + "\n")
-
- info = critical
- debug = critical
-
-# Null logger is used when no output is generated. Does nothing.
-class NullLogger(object):
- def __getattribute__(self,name):
- return self
- def __call__(self,*args,**kwargs):
- return self
-
-# -----------------------------------------------------------------------------
-# === Lexing Engine ===
-#
-# The following Lexer class implements the lexer runtime. There are only
-# a few public methods and attributes:
-#
-# input() - Store a new string in the lexer
-# token() - Get the next token
-# clone() - Clone the lexer
-#
-# lineno - Current line number
-# lexpos - Current position in the input string
-# -----------------------------------------------------------------------------
-
-class Lexer:
- def __init__(self):
- self.lexre = None # Master regular expression. This is a list of
- # tuples (re,findex) where re is a compiled
- # regular expression and findex is a list
- # mapping regex group numbers to rules
- self.lexretext = None # Current regular expression strings
- self.lexstatere = {} # Dictionary mapping lexer states to master regexs
- self.lexstateretext = {} # Dictionary mapping lexer states to regex strings
- self.lexstaterenames = {} # Dictionary mapping lexer states to symbol names
- self.lexstate = "INITIAL" # Current lexer state
- self.lexstatestack = [] # Stack of lexer states
- self.lexstateinfo = None # State information
- self.lexstateignore = {} # Dictionary of ignored characters for each state
- self.lexstateerrorf = {} # Dictionary of error functions for each state
- self.lexreflags = 0 # Optional re compile flags
- self.lexdata = None # Actual input data (as a string)
- self.lexpos = 0 # Current position in input text
- self.lexlen = 0 # Length of the input text
- self.lexerrorf = None # Error rule (if any)
- self.lextokens = None # List of valid tokens
- self.lexignore = "" # Ignored characters
- self.lexliterals = "" # Literal characters that can be passed through
- self.lexmodule = None # Module
- self.lineno = 1 # Current line number
- self.lexoptimize = 0 # Optimized mode
-
- def clone(self,object=None):
- c = copy.copy(self)
-
- # If the object parameter has been supplied, it means we are attaching the
- # lexer to a new object. In this case, we have to rebind all methods in
- # the lexstatere and lexstateerrorf tables.
-
- if object:
- newtab = { }
- for key, ritem in self.lexstatere.items():
- newre = []
- for cre, findex in ritem:
- newfindex = []
- for f in findex:
- if not f or not f[0]:
- newfindex.append(f)
- continue
- newfindex.append((getattr(object,f[0].__name__),f[1]))
- newre.append((cre,newfindex))
- newtab[key] = newre
- c.lexstatere = newtab
- c.lexstateerrorf = { }
- for key, ef in self.lexstateerrorf.items():
- c.lexstateerrorf[key] = getattr(object,ef.__name__)
- c.lexmodule = object
- return c
-
- # ------------------------------------------------------------
- # writetab() - Write lexer information to a table file
- # ------------------------------------------------------------
- def writetab(self,tabfile,outputdir=""):
- if isinstance(tabfile,types.ModuleType):
- return
- basetabfilename = tabfile.split(".")[-1]
- filename = os.path.join(outputdir,basetabfilename)+".py"
- tf = open(filename,"w")
- tf.write("# %s.py. This file automatically created by PLY (version %s). Don't edit!\n" % (tabfile,__version__))
- tf.write("_tabversion = %s\n" % repr(__version__))
- tf.write("_lextokens = %s\n" % repr(self.lextokens))
- tf.write("_lexreflags = %s\n" % repr(self.lexreflags))
- tf.write("_lexliterals = %s\n" % repr(self.lexliterals))
- tf.write("_lexstateinfo = %s\n" % repr(self.lexstateinfo))
-
- tabre = { }
- # Collect all functions in the initial state
- initial = self.lexstatere["INITIAL"]
- initialfuncs = []
- for part in initial:
- for f in part[1]:
- if f and f[0]:
- initialfuncs.append(f)
-
- for key, lre in self.lexstatere.items():
- titem = []
- for i in range(len(lre)):
- titem.append((self.lexstateretext[key][i],_funcs_to_names(lre[i][1],self.lexstaterenames[key][i])))
- tabre[key] = titem
-
- tf.write("_lexstatere = %s\n" % repr(tabre))
- tf.write("_lexstateignore = %s\n" % repr(self.lexstateignore))
-
- taberr = { }
- for key, ef in self.lexstateerrorf.items():
- if ef:
- taberr[key] = ef.__name__
- else:
- taberr[key] = None
- tf.write("_lexstateerrorf = %s\n" % repr(taberr))
- tf.close()
-
- # ------------------------------------------------------------
- # readtab() - Read lexer information from a tab file
- # ------------------------------------------------------------
- def readtab(self,tabfile,fdict):
- if isinstance(tabfile,types.ModuleType):
- lextab = tabfile
- else:
- if sys.version_info[0] < 3:
- exec("import %s as lextab" % tabfile)
- else:
- env = { }
- exec("import %s as lextab" % tabfile, env,env)
- lextab = env['lextab']
-
- if getattr(lextab,"_tabversion","0.0") != __version__:
- raise ImportError("Inconsistent PLY version")
-
- self.lextokens = lextab._lextokens
- self.lexreflags = lextab._lexreflags
- self.lexliterals = lextab._lexliterals
- self.lexstateinfo = lextab._lexstateinfo
- self.lexstateignore = lextab._lexstateignore
- self.lexstatere = { }
- self.lexstateretext = { }
- for key,lre in lextab._lexstatere.items():
- titem = []
- txtitem = []
- for i in range(len(lre)):
- titem.append((re.compile(lre[i][0],lextab._lexreflags | re.VERBOSE),_names_to_funcs(lre[i][1],fdict)))
- txtitem.append(lre[i][0])
- self.lexstatere[key] = titem
- self.lexstateretext[key] = txtitem
- self.lexstateerrorf = { }
- for key,ef in lextab._lexstateerrorf.items():
- self.lexstateerrorf[key] = fdict[ef]
- self.begin('INITIAL')
-
- # ------------------------------------------------------------
- # input() - Push a new string into the lexer
- # ------------------------------------------------------------
- def input(self,s):
- # Pull off the first character to see if s looks like a string
- c = s[:1]
- if not isinstance(c,StringTypes):
- raise ValueError("Expected a string")
- self.lexdata = s
- self.lexpos = 0
- self.lexlen = len(s)
-
- # ------------------------------------------------------------
- # begin() - Changes the lexing state
- # ------------------------------------------------------------
- def begin(self,state):
- if not state in self.lexstatere:
- raise ValueError("Undefined state")
- self.lexre = self.lexstatere[state]
- self.lexretext = self.lexstateretext[state]
- self.lexignore = self.lexstateignore.get(state,"")
- self.lexerrorf = self.lexstateerrorf.get(state,None)
- self.lexstate = state
-
- # ------------------------------------------------------------
- # push_state() - Changes the lexing state and saves old on stack
- # ------------------------------------------------------------
- def push_state(self,state):
- self.lexstatestack.append(self.lexstate)
- self.begin(state)
-
- # ------------------------------------------------------------
- # pop_state() - Restores the previous state
- # ------------------------------------------------------------
- def pop_state(self):
- self.begin(self.lexstatestack.pop())
-
- # ------------------------------------------------------------
- # current_state() - Returns the current lexing state
- # ------------------------------------------------------------
- def current_state(self):
- return self.lexstate
-
- # ------------------------------------------------------------
- # skip() - Skip ahead n characters
- # ------------------------------------------------------------
- def skip(self,n):
- self.lexpos += n
-
- # ------------------------------------------------------------
- # opttoken() - Return the next token from the Lexer
- #
- # Note: This function has been carefully implemented to be as fast
- # as possible. Don't make changes unless you really know what
- # you are doing
- # ------------------------------------------------------------
- def token(self):
- # Make local copies of frequently referenced attributes
- lexpos = self.lexpos
- lexlen = self.lexlen
- lexignore = self.lexignore
- lexdata = self.lexdata
-
- while lexpos < lexlen:
- # This code provides some short-circuit code for whitespace, tabs, and other ignored characters
- if lexdata[lexpos] in lexignore:
- lexpos += 1
- continue
-
- # Look for a regular expression match
- for lexre,lexindexfunc in self.lexre:
- m = lexre.match(lexdata,lexpos)
- if not m: continue
-
- # Create a token for return
- tok = LexToken()
- tok.value = m.group()
- tok.lineno = self.lineno
- tok.lexpos = lexpos
-
- i = m.lastindex
- func,tok.type = lexindexfunc[i]
-
- if not func:
- # If no token type was set, it's an ignored token
- if tok.type:
- self.lexpos = m.end()
- return tok
- else:
- lexpos = m.end()
- break
-
- lexpos = m.end()
-
- # If token is processed by a function, call it
-
- tok.lexer = self # Set additional attributes useful in token rules
- self.lexmatch = m
- self.lexpos = lexpos
-
- newtok = func(tok)
-
- # Every function must return a token, if nothing, we just move to next token
- if not newtok:
- lexpos = self.lexpos # This is here in case user has updated lexpos.
- lexignore = self.lexignore # This is here in case there was a state change
- break
-
- # Verify type of the token. If not in the token map, raise an error
- if not self.lexoptimize:
- if not newtok.type in self.lextokens:
- raise LexError("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
- func_code(func).co_filename, func_code(func).co_firstlineno,
- func.__name__, newtok.type),lexdata[lexpos:])
-
- return newtok
- else:
- # No match, see if in literals
- if lexdata[lexpos] in self.lexliterals:
- tok = LexToken()
- tok.value = lexdata[lexpos]
- tok.lineno = self.lineno
- tok.type = tok.value
- tok.lexpos = lexpos
- self.lexpos = lexpos + 1
- return tok
-
- # No match. Call t_error() if defined.
- if self.lexerrorf:
- tok = LexToken()
- tok.value = self.lexdata[lexpos:]
- tok.lineno = self.lineno
- tok.type = "error"
- tok.lexer = self
- tok.lexpos = lexpos
- self.lexpos = lexpos
- newtok = self.lexerrorf(tok)
- if lexpos == self.lexpos:
- # Error method didn't change text position at all. This is an error.
- raise LexError("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
- lexpos = self.lexpos
- if not newtok: continue
- return newtok
-
- self.lexpos = lexpos
- raise LexError("Illegal character '%s' at index %d" % (lexdata[lexpos],lexpos), lexdata[lexpos:])
-
- self.lexpos = lexpos + 1
- if self.lexdata is None:
- raise RuntimeError("No input string given with input()")
- return None
-
- # Iterator interface
- def __iter__(self):
- return self
-
- def next(self):
- t = self.token()
- if t is None:
- raise StopIteration
- return t
-
- __next__ = next
-
-# -----------------------------------------------------------------------------
-# ==== Lex Builder ===
-#
-# The functions and classes below are used to collect lexing information
-# and build a Lexer object from it.
-# -----------------------------------------------------------------------------
-
-# -----------------------------------------------------------------------------
-# get_caller_module_dict()
-#
-# This function returns a dictionary containing all of the symbols defined within
-# a caller further down the call stack. This is used to get the environment
-# associated with the yacc() call if none was provided.
-# -----------------------------------------------------------------------------
-
-def get_caller_module_dict(levels):
- try:
- raise RuntimeError
- except RuntimeError:
- e,b,t = sys.exc_info()
- f = t.tb_frame
- while levels > 0:
- f = f.f_back
- levels -= 1
- ldict = f.f_globals.copy()
- if f.f_globals != f.f_locals:
- ldict.update(f.f_locals)
-
- return ldict
-
-# -----------------------------------------------------------------------------
-# _funcs_to_names()
-#
-# Given a list of regular expression functions, this converts it to a list
-# suitable for output to a table file
-# -----------------------------------------------------------------------------
-
-def _funcs_to_names(funclist,namelist):
- result = []
- for f,name in zip(funclist,namelist):
- if f and f[0]:
- result.append((name, f[1]))
- else:
- result.append(f)
- return result
-
-# -----------------------------------------------------------------------------
-# _names_to_funcs()
-#
-# Given a list of regular expression function names, this converts it back to
-# functions.
-# -----------------------------------------------------------------------------
-
-def _names_to_funcs(namelist,fdict):
- result = []
- for n in namelist:
- if n and n[0]:
- result.append((fdict[n[0]],n[1]))
- else:
- result.append(n)
- return result
-
-# -----------------------------------------------------------------------------
-# _form_master_re()
-#
-# This function takes a list of all of the regex components and attempts to
-# form the master regular expression. Given limitations in the Python re
-# module, it may be necessary to break the master regex into separate expressions.
-# -----------------------------------------------------------------------------
-
-def _form_master_re(relist,reflags,ldict,toknames):
- if not relist: return []
- regex = "|".join(relist)
- try:
- lexre = re.compile(regex,re.VERBOSE | reflags)
-
- # Build the index to function map for the matching engine
- lexindexfunc = [ None ] * (max(lexre.groupindex.values())+1)
- lexindexnames = lexindexfunc[:]
-
- for f,i in lexre.groupindex.items():
- handle = ldict.get(f,None)
- if type(handle) in (types.FunctionType, types.MethodType):
- lexindexfunc[i] = (handle,toknames[f])
- lexindexnames[i] = f
- elif handle is not None:
- lexindexnames[i] = f
- if f.find("ignore_") > 0:
- lexindexfunc[i] = (None,None)
- else:
- lexindexfunc[i] = (None, toknames[f])
-
- return [(lexre,lexindexfunc)],[regex],[lexindexnames]
- except Exception:
- m = int(len(relist)/2)
- if m == 0: m = 1
- llist, lre, lnames = _form_master_re(relist[:m],reflags,ldict,toknames)
- rlist, rre, rnames = _form_master_re(relist[m:],reflags,ldict,toknames)
- return llist+rlist, lre+rre, lnames+rnames
-
-# -----------------------------------------------------------------------------
-# def _statetoken(s,names)
-#
-# Given a declaration name s of the form "t_" and a dictionary whose keys are
-# state names, this function returns a tuple (states,tokenname) where states
-# is a tuple of state names and tokenname is the name of the token. For example,
-# calling this with s = "t_foo_bar_SPAM" might return (('foo','bar'),'SPAM')
-# -----------------------------------------------------------------------------
-
-def _statetoken(s,names):
- nonstate = 1
- parts = s.split("_")
- for i in range(1,len(parts)):
- if not parts[i] in names and parts[i] != 'ANY': break
- if i > 1:
- states = tuple(parts[1:i])
- else:
- states = ('INITIAL',)
-
- if 'ANY' in states:
- states = tuple(names)
-
- tokenname = "_".join(parts[i:])
- return (states,tokenname)
-
-
-# -----------------------------------------------------------------------------
-# LexerReflect()
-#
-# This class represents information needed to build a lexer as extracted from a
-# user's input file.
-# -----------------------------------------------------------------------------
-class LexerReflect(object):
- def __init__(self,ldict,log=None,reflags=0):
- self.ldict = ldict
- self.error_func = None
- self.tokens = []
- self.reflags = reflags
- self.stateinfo = { 'INITIAL' : 'inclusive'}
- self.files = {}
- self.error = 0
-
- if log is None:
- self.log = PlyLogger(sys.stderr)
- else:
- self.log = log
-
- # Get all of the basic information
- def get_all(self):
- self.get_tokens()
- self.get_literals()
- self.get_states()
- self.get_rules()
-
- # Validate all of the information
- def validate_all(self):
- self.validate_tokens()
- self.validate_literals()
- self.validate_rules()
- return self.error
-
- # Get the tokens map
- def get_tokens(self):
- tokens = self.ldict.get("tokens",None)
- if not tokens:
- self.log.error("No token list is defined")
- self.error = 1
- return
-
- if not isinstance(tokens,(list, tuple)):
- self.log.error("tokens must be a list or tuple")
- self.error = 1
- return
-
- if not tokens:
- self.log.error("tokens is empty")
- self.error = 1
- return
-
- self.tokens = tokens
-
- # Validate the tokens
- def validate_tokens(self):
- terminals = {}
- for n in self.tokens:
- if not _is_identifier.match(n):
- self.log.error("Bad token name '%s'",n)
- self.error = 1
- if n in terminals:
- self.log.warning("Token '%s' multiply defined", n)
- terminals[n] = 1
-
- # Get the literals specifier
- def get_literals(self):
- self.literals = self.ldict.get("literals","")
-
- # Validate literals
- def validate_literals(self):
- try:
- for c in self.literals:
- if not isinstance(c,StringTypes) or len(c) > 1:
- self.log.error("Invalid literal %s. Must be a single character", repr(c))
- self.error = 1
- continue
-
- except TypeError:
- self.log.error("Invalid literals specification. literals must be a sequence of characters")
- self.error = 1
-
- def get_states(self):
- self.states = self.ldict.get("states",None)
- # Build statemap
- if self.states:
- if not isinstance(self.states,(tuple,list)):
- self.log.error("states must be defined as a tuple or list")
- self.error = 1
- else:
- for s in self.states:
- if not isinstance(s,tuple) or len(s) != 2:
- self.log.error("Invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')",repr(s))
- self.error = 1
- continue
- name, statetype = s
- if not isinstance(name,StringTypes):
- self.log.error("State name %s must be a string", repr(name))
- self.error = 1
- continue
- if not (statetype == 'inclusive' or statetype == 'exclusive'):
- self.log.error("State type for state %s must be 'inclusive' or 'exclusive'",name)
- self.error = 1
- continue
- if name in self.stateinfo:
- self.log.error("State '%s' already defined",name)
- self.error = 1
- continue
- self.stateinfo[name] = statetype
-
- # Get all of the symbols with a t_ prefix and sort them into various
- # categories (functions, strings, error functions, and ignore characters)
-
- def get_rules(self):
- tsymbols = [f for f in self.ldict if f[:2] == 't_' ]
-
- # Now build up a list of functions and a list of strings
-
- self.toknames = { } # Mapping of symbols to token names
- self.funcsym = { } # Symbols defined as functions
- self.strsym = { } # Symbols defined as strings
- self.ignore = { } # Ignore strings by state
- self.errorf = { } # Error functions by state
-
- for s in self.stateinfo:
- self.funcsym[s] = []
- self.strsym[s] = []
-
- if len(tsymbols) == 0:
- self.log.error("No rules of the form t_rulename are defined")
- self.error = 1
- return
-
- for f in tsymbols:
- t = self.ldict[f]
- states, tokname = _statetoken(f,self.stateinfo)
- self.toknames[f] = tokname
-
- if hasattr(t,"__call__"):
- if tokname == 'error':
- for s in states:
- self.errorf[s] = t
- elif tokname == 'ignore':
- line = func_code(t).co_firstlineno
- file = func_code(t).co_filename
- self.log.error("%s:%d: Rule '%s' must be defined as a string",file,line,t.__name__)
- self.error = 1
- else:
- for s in states:
- self.funcsym[s].append((f,t))
- elif isinstance(t, StringTypes):
- if tokname == 'ignore':
- for s in states:
- self.ignore[s] = t
- if "\\" in t:
- self.log.warning("%s contains a literal backslash '\\'",f)
-
- elif tokname == 'error':
- self.log.error("Rule '%s' must be defined as a function", f)
- self.error = 1
- else:
- for s in states:
- self.strsym[s].append((f,t))
- else:
- self.log.error("%s not defined as a function or string", f)
- self.error = 1
-
- # Sort the functions by line number
- for f in self.funcsym.values():
- if sys.version_info[0] < 3:
- f.sort(lambda x,y: cmp(func_code(x[1]).co_firstlineno,func_code(y[1]).co_firstlineno))
- else:
- # Python 3.0
- f.sort(key=lambda x: func_code(x[1]).co_firstlineno)
-
- # Sort the strings by regular expression length
- for s in self.strsym.values():
- if sys.version_info[0] < 3:
- s.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1])))
- else:
- # Python 3.0
- s.sort(key=lambda x: len(x[1]),reverse=True)
-
- # Validate all of the t_rules collected
- def validate_rules(self):
- for state in self.stateinfo:
- # Validate all rules defined by functions
-
-
-
- for fname, f in self.funcsym[state]:
- line = func_code(f).co_firstlineno
- file = func_code(f).co_filename
- self.files[file] = 1
-
- tokname = self.toknames[fname]
- if isinstance(f, types.MethodType):
- reqargs = 2
- else:
- reqargs = 1
- nargs = func_code(f).co_argcount
- if nargs > reqargs:
- self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,f.__name__)
- self.error = 1
- continue
-
- if nargs < reqargs:
- self.log.error("%s:%d: Rule '%s' requires an argument", file,line,f.__name__)
- self.error = 1
- continue
-
- if not f.__doc__:
- self.log.error("%s:%d: No regular expression defined for rule '%s'",file,line,f.__name__)
- self.error = 1
- continue
-
- try:
- c = re.compile("(?P<%s>%s)" % (fname,f.__doc__), re.VERBOSE | self.reflags)
- if c.match(""):
- self.log.error("%s:%d: Regular expression for rule '%s' matches empty string", file,line,f.__name__)
- self.error = 1
- except re.error:
- _etype, e, _etrace = sys.exc_info()
- self.log.error("%s:%d: Invalid regular expression for rule '%s'. %s", file,line,f.__name__,e)
- if '#' in f.__doc__:
- self.log.error("%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'",file,line, f.__name__)
- self.error = 1
-
- # Validate all rules defined by strings
- for name,r in self.strsym[state]:
- tokname = self.toknames[name]
- if tokname == 'error':
- self.log.error("Rule '%s' must be defined as a function", name)
- self.error = 1
- continue
-
- if not tokname in self.tokens and tokname.find("ignore_") < 0:
- self.log.error("Rule '%s' defined for an unspecified token %s",name,tokname)
- self.error = 1
- continue
-
- try:
- c = re.compile("(?P<%s>%s)" % (name,r),re.VERBOSE | self.reflags)
- if (c.match("")):
- self.log.error("Regular expression for rule '%s' matches empty string",name)
- self.error = 1
- except re.error:
- _etype, e, _etrace = sys.exc_info()
- self.log.error("Invalid regular expression for rule '%s'. %s",name,e)
- if '#' in r:
- self.log.error("Make sure '#' in rule '%s' is escaped with '\\#'",name)
- self.error = 1
-
- if not self.funcsym[state] and not self.strsym[state]:
- self.log.error("No rules defined for state '%s'",state)
- self.error = 1
-
- # Validate the error function
- efunc = self.errorf.get(state,None)
- if efunc:
- f = efunc
- line = func_code(f).co_firstlineno
- file = func_code(f).co_filename
- self.files[file] = 1
-
- if isinstance(f, types.MethodType):
- reqargs = 2
- else:
- reqargs = 1
- nargs = func_code(f).co_argcount
- if nargs > reqargs:
- self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,f.__name__)
- self.error = 1
-
- if nargs < reqargs:
- self.log.error("%s:%d: Rule '%s' requires an argument", file,line,f.__name__)
- self.error = 1
-
- for f in self.files:
- self.validate_file(f)
-
-
- # -----------------------------------------------------------------------------
- # validate_file()
- #
- # This checks to see if there are duplicated t_rulename() functions or strings
- # in the parser input file. This is done using a simple regular expression
- # match on each line in the given file.
- # -----------------------------------------------------------------------------
-
- def validate_file(self,filename):
- import os.path
- base,ext = os.path.splitext(filename)
- if ext != '.py': return # No idea what the file is. Return OK
-
- try:
- f = open(filename)
- lines = f.readlines()
- f.close()
- except IOError:
- return # Couldn't find the file. Don't worry about it
-
- fre = re.compile(r'\s*def\s+(t_[a-zA-Z_0-9]*)\(')
- sre = re.compile(r'\s*(t_[a-zA-Z_0-9]*)\s*=')
-
- counthash = { }
- linen = 1
- for l in lines:
- m = fre.match(l)
- if not m:
- m = sre.match(l)
- if m:
- name = m.group(1)
- prev = counthash.get(name)
- if not prev:
- counthash[name] = linen
- else:
- self.log.error("%s:%d: Rule %s redefined. Previously defined on line %d",filename,linen,name,prev)
- self.error = 1
- linen += 1
-
-# -----------------------------------------------------------------------------
-# lex(module)
-#
-# Build all of the regular expression rules from definitions in the supplied module
-# -----------------------------------------------------------------------------
-def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,nowarn=0,outputdir="", debuglog=None, errorlog=None):
- global lexer
- ldict = None
- stateinfo = { 'INITIAL' : 'inclusive'}
- lexobj = Lexer()
- lexobj.lexoptimize = optimize
- global token,input
-
- if errorlog is None:
- errorlog = PlyLogger(sys.stderr)
-
- if debug:
- if debuglog is None:
- debuglog = PlyLogger(sys.stderr)
-
- # Get the module dictionary used for the lexer
- if object: module = object
-
- if module:
- _items = [(k,getattr(module,k)) for k in dir(module)]
- ldict = dict(_items)
- else:
- ldict = get_caller_module_dict(2)
-
- # Collect parser information from the dictionary
- linfo = LexerReflect(ldict,log=errorlog,reflags=reflags)
- linfo.get_all()
- if not optimize:
- if linfo.validate_all():
- raise SyntaxError("Can't build lexer")
-
- if optimize and lextab:
- try:
- lexobj.readtab(lextab,ldict)
- token = lexobj.token
- input = lexobj.input
- lexer = lexobj
- return lexobj
-
- except ImportError:
- pass
-
- # Dump some basic debugging information
- if debug:
- debuglog.info("lex: tokens = %r", linfo.tokens)
- debuglog.info("lex: literals = %r", linfo.literals)
- debuglog.info("lex: states = %r", linfo.stateinfo)
-
- # Build a dictionary of valid token names
- lexobj.lextokens = { }
- for n in linfo.tokens:
- lexobj.lextokens[n] = 1
-
- # Get literals specification
- if isinstance(linfo.literals,(list,tuple)):
- lexobj.lexliterals = type(linfo.literals[0])().join(linfo.literals)
- else:
- lexobj.lexliterals = linfo.literals
-
- # Get the stateinfo dictionary
- stateinfo = linfo.stateinfo
-
- regexs = { }
- # Build the master regular expressions
- for state in stateinfo:
- regex_list = []
-
- # Add rules defined by functions first
- for fname, f in linfo.funcsym[state]:
- line = func_code(f).co_firstlineno
- file = func_code(f).co_filename
- regex_list.append("(?P<%s>%s)" % (fname,f.__doc__))
- if debug:
- debuglog.info("lex: Adding rule %s -> '%s' (state '%s')",fname,f.__doc__, state)
-
- # Now add all of the simple rules
- for name,r in linfo.strsym[state]:
- regex_list.append("(?P<%s>%s)" % (name,r))
- if debug:
- debuglog.info("lex: Adding rule %s -> '%s' (state '%s')",name,r, state)
-
- regexs[state] = regex_list
-
- # Build the master regular expressions
-
- if debug:
- debuglog.info("lex: ==== MASTER REGEXS FOLLOW ====")
-
- for state in regexs:
- lexre, re_text, re_names = _form_master_re(regexs[state],reflags,ldict,linfo.toknames)
- lexobj.lexstatere[state] = lexre
- lexobj.lexstateretext[state] = re_text
- lexobj.lexstaterenames[state] = re_names
- if debug:
- for i in range(len(re_text)):
- debuglog.info("lex: state '%s' : regex[%d] = '%s'",state, i, re_text[i])
-
- # For inclusive states, we need to add the regular expressions from the INITIAL state
- for state,stype in stateinfo.items():
- if state != "INITIAL" and stype == 'inclusive':
- lexobj.lexstatere[state].extend(lexobj.lexstatere['INITIAL'])
- lexobj.lexstateretext[state].extend(lexobj.lexstateretext['INITIAL'])
- lexobj.lexstaterenames[state].extend(lexobj.lexstaterenames['INITIAL'])
-
- lexobj.lexstateinfo = stateinfo
- lexobj.lexre = lexobj.lexstatere["INITIAL"]
- lexobj.lexretext = lexobj.lexstateretext["INITIAL"]
- lexobj.lexreflags = reflags
-
- # Set up ignore variables
- lexobj.lexstateignore = linfo.ignore
- lexobj.lexignore = lexobj.lexstateignore.get("INITIAL","")
-
- # Set up error functions
- lexobj.lexstateerrorf = linfo.errorf
- lexobj.lexerrorf = linfo.errorf.get("INITIAL",None)
- if not lexobj.lexerrorf:
- errorlog.warning("No t_error rule is defined")
-
- # Check state information for ignore and error rules
- for s,stype in stateinfo.items():
- if stype == 'exclusive':
- if not s in linfo.errorf:
- errorlog.warning("No error rule is defined for exclusive state '%s'", s)
- if not s in linfo.ignore and lexobj.lexignore:
- errorlog.warning("No ignore rule is defined for exclusive state '%s'", s)
- elif stype == 'inclusive':
- if not s in linfo.errorf:
- linfo.errorf[s] = linfo.errorf.get("INITIAL",None)
- if not s in linfo.ignore:
- linfo.ignore[s] = linfo.ignore.get("INITIAL","")
-
- # Create global versions of the token() and input() functions
- token = lexobj.token
- input = lexobj.input
- lexer = lexobj
-
- # If in optimize mode, we write the lextab
- if lextab and optimize:
- lexobj.writetab(lextab,outputdir)
-
- return lexobj
-
-# -----------------------------------------------------------------------------
-# runmain()
-#
-# This runs the lexer as a main program
-# -----------------------------------------------------------------------------
-
-def runmain(lexer=None,data=None):
- if not data:
- try:
- filename = sys.argv[1]
- f = open(filename)
- data = f.read()
- f.close()
- except IndexError:
- sys.stdout.write("Reading from standard input (type EOF to end):\n")
- data = sys.stdin.read()
-
- if lexer:
- _input = lexer.input
- else:
- _input = input
- _input(data)
- if lexer:
- _token = lexer.token
- else:
- _token = token
-
- while 1:
- tok = _token()
- if not tok: break
- sys.stdout.write("(%s,%r,%d,%d)\n" % (tok.type, tok.value, tok.lineno,tok.lexpos))
-
-# -----------------------------------------------------------------------------
-# @TOKEN(regex)
-#
-# This decorator function can be used to set the regex expression on a function
-# when its docstring might need to be set in an alternative way
-# -----------------------------------------------------------------------------
-
-def TOKEN(r):
- def set_doc(f):
- if hasattr(r,"__call__"):
- f.__doc__ = r.__doc__
- else:
- f.__doc__ = r
- return f
- return set_doc
-
-# Alternative spelling of the TOKEN decorator
-Token = TOKEN
-
diff --git a/src/components/script/dom/bindings/codegen/ply/ply/yacc.py b/src/components/script/dom/bindings/codegen/ply/ply/yacc.py
deleted file mode 100644
index e9f5c657551..00000000000
--- a/src/components/script/dom/bindings/codegen/ply/ply/yacc.py
+++ /dev/null
@@ -1,3276 +0,0 @@
-# -----------------------------------------------------------------------------
-# ply: yacc.py
-#
-# Copyright (C) 2001-2009,
-# David M. Beazley (Dabeaz LLC)
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of the David Beazley or Dabeaz LLC may be used to
-# endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# -----------------------------------------------------------------------------
-#
-# This implements an LR parser that is constructed from grammar rules defined
-# as Python functions. The grammer is specified by supplying the BNF inside
-# Python documentation strings. The inspiration for this technique was borrowed
-# from John Aycock's Spark parsing system. PLY might be viewed as cross between
-# Spark and the GNU bison utility.
-#
-# The current implementation is only somewhat object-oriented. The
-# LR parser itself is defined in terms of an object (which allows multiple
-# parsers to co-exist). However, most of the variables used during table
-# construction are defined in terms of global variables. Users shouldn't
-# notice unless they are trying to define multiple parsers at the same
-# time using threads (in which case they should have their head examined).
-#
-# This implementation supports both SLR and LALR(1) parsing. LALR(1)
-# support was originally implemented by Elias Ioup (ezioup@alumni.uchicago.edu),
-# using the algorithm found in Aho, Sethi, and Ullman "Compilers: Principles,
-# Techniques, and Tools" (The Dragon Book). LALR(1) has since been replaced
-# by the more efficient DeRemer and Pennello algorithm.
-#
-# :::::::: WARNING :::::::
-#
-# Construction of LR parsing tables is fairly complicated and expensive.
-# To make this module run fast, a *LOT* of work has been put into
-# optimization---often at the expensive of readability and what might
-# consider to be good Python "coding style." Modify the code at your
-# own risk!
-# ----------------------------------------------------------------------------
-
-__version__ = "3.3"
-__tabversion__ = "3.2" # Table version
-
-#-----------------------------------------------------------------------------
-# === User configurable parameters ===
-#
-# Change these to modify the default behavior of yacc (if you wish)
-#-----------------------------------------------------------------------------
-
-yaccdebug = 1 # Debugging mode. If set, yacc generates a
- # a 'parser.out' file in the current directory
-
-debug_file = 'parser.out' # Default name of the debugging file
-tab_module = 'parsetab' # Default name of the table module
-default_lr = 'LALR' # Default LR table generation method
-
-error_count = 3 # Number of symbols that must be shifted to leave recovery mode
-
-yaccdevel = 0 # Set to True if developing yacc. This turns off optimized
- # implementations of certain functions.
-
-resultlimit = 40 # Size limit of results when running in debug mode.
-
-pickle_protocol = 0 # Protocol to use when writing pickle files
-
-import re, types, sys, os.path
-
-# Compatibility function for python 2.6/3.0
-if sys.version_info[0] < 3:
- def func_code(f):
- return f.func_code
-else:
- def func_code(f):
- return f.__code__
-
-# Compatibility
-try:
- MAXINT = sys.maxint
-except AttributeError:
- MAXINT = sys.maxsize
-
-# Python 2.x/3.0 compatibility.
-def load_ply_lex():
- if sys.version_info[0] < 3:
- import lex
- else:
- import ply.lex as lex
- return lex
-
-# This object is a stand-in for a logging object created by the
-# logging module. PLY will use this by default to create things
-# such as the parser.out file. If a user wants more detailed
-# information, they can create their own logging object and pass
-# it into PLY.
-
-class PlyLogger(object):
- def __init__(self,f):
- self.f = f
- def debug(self,msg,*args,**kwargs):
- self.f.write((msg % args) + "\n")
- info = debug
-
- def warning(self,msg,*args,**kwargs):
- self.f.write("WARNING: "+ (msg % args) + "\n")
-
- def error(self,msg,*args,**kwargs):
- self.f.write("ERROR: " + (msg % args) + "\n")
-
- critical = debug
-
-# Null logger is used when no output is generated. Does nothing.
-class NullLogger(object):
- def __getattribute__(self,name):
- return self
- def __call__(self,*args,**kwargs):
- return self
-
-# Exception raised for yacc-related errors
-class YaccError(Exception): pass
-
-# Format the result message that the parser produces when running in debug mode.
-def format_result(r):
- repr_str = repr(r)
- if '\n' in repr_str: repr_str = repr(repr_str)
- if len(repr_str) > resultlimit:
- repr_str = repr_str[:resultlimit]+" ..."
- result = "<%s @ 0x%x> (%s)" % (type(r).__name__,id(r),repr_str)
- return result
-
-
-# Format stack entries when the parser is running in debug mode
-def format_stack_entry(r):
- repr_str = repr(r)
- if '\n' in repr_str: repr_str = repr(repr_str)
- if len(repr_str) < 16:
- return repr_str
- else:
- return "<%s @ 0x%x>" % (type(r).__name__,id(r))
-
-#-----------------------------------------------------------------------------
-# === LR Parsing Engine ===
-#
-# The following classes are used for the LR parser itself. These are not
-# used during table construction and are independent of the actual LR
-# table generation algorithm
-#-----------------------------------------------------------------------------
-
-# This class is used to hold non-terminal grammar symbols during parsing.
-# It normally has the following attributes set:
-# .type = Grammar symbol type
-# .value = Symbol value
-# .lineno = Starting line number
-# .endlineno = Ending line number (optional, set automatically)
-# .lexpos = Starting lex position
-# .endlexpos = Ending lex position (optional, set automatically)
-
-class YaccSymbol:
- def __str__(self): return self.type
- def __repr__(self): return str(self)
-
-# This class is a wrapper around the objects actually passed to each
-# grammar rule. Index lookup and assignment actually assign the
-# .value attribute of the underlying YaccSymbol object.
-# The lineno() method returns the line number of a given
-# item (or 0 if not defined). The linespan() method returns
-# a tuple of (startline,endline) representing the range of lines
-# for a symbol. The lexspan() method returns a tuple (lexpos,endlexpos)
-# representing the range of positional information for a symbol.
-
-class YaccProduction:
- def __init__(self,s,stack=None):
- self.slice = s
- self.stack = stack
- self.lexer = None
- self.parser= None
- def __getitem__(self,n):
- if n >= 0: return self.slice[n].value
- else: return self.stack[n].value
-
- def __setitem__(self,n,v):
- self.slice[n].value = v
-
- def __getslice__(self,i,j):
- return [s.value for s in self.slice[i:j]]
-
- def __len__(self):
- return len(self.slice)
-
- def lineno(self,n):
- return getattr(self.slice[n],"lineno",0)
-
- def set_lineno(self,n,lineno):
- self.slice[n].lineno = lineno
-
- def linespan(self,n):
- startline = getattr(self.slice[n],"lineno",0)
- endline = getattr(self.slice[n],"endlineno",startline)
- return startline,endline
-
- def lexpos(self,n):
- return getattr(self.slice[n],"lexpos",0)
-
- def lexspan(self,n):
- startpos = getattr(self.slice[n],"lexpos",0)
- endpos = getattr(self.slice[n],"endlexpos",startpos)
- return startpos,endpos
-
- def error(self):
- raise SyntaxError
-
-
-# -----------------------------------------------------------------------------
-# == LRParser ==
-#
-# The LR Parsing engine.
-# -----------------------------------------------------------------------------
-
-class LRParser:
- def __init__(self,lrtab,errorf):
- self.productions = lrtab.lr_productions
- self.action = lrtab.lr_action
- self.goto = lrtab.lr_goto
- self.errorfunc = errorf
-
- def errok(self):
- self.errorok = 1
-
- def restart(self):
- del self.statestack[:]
- del self.symstack[:]
- sym = YaccSymbol()
- sym.type = '$end'
- self.symstack.append(sym)
- self.statestack.append(0)
-
- def parse(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None):
- if debug or yaccdevel:
- if isinstance(debug,int):
- debug = PlyLogger(sys.stderr)
- return self.parsedebug(input,lexer,debug,tracking,tokenfunc)
- elif tracking:
- return self.parseopt(input,lexer,debug,tracking,tokenfunc)
- else:
- return self.parseopt_notrack(input,lexer,debug,tracking,tokenfunc)
-
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # parsedebug().
- #
- # This is the debugging enabled version of parse(). All changes made to the
- # parsing engine should be made here. For the non-debugging version,
- # copy this code to a method parseopt() and delete all of the sections
- # enclosed in:
- #
- # #--! DEBUG
- # statements
- # #--! DEBUG
- #
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- def parsedebug(self,input=None,lexer=None,debug=None,tracking=0,tokenfunc=None):
- lookahead = None # Current lookahead symbol
- lookaheadstack = [ ] # Stack of lookahead symbols
- actions = self.action # Local reference to action table (to avoid lookup on self.)
- goto = self.goto # Local reference to goto table (to avoid lookup on self.)
- prod = self.productions # Local reference to production list (to avoid lookup on self.)
- pslice = YaccProduction(None) # Production object passed to grammar rules
- errorcount = 0 # Used during error recovery
-
- # --! DEBUG
- debug.info("PLY: PARSE DEBUG START")
- # --! DEBUG
-
- # If no lexer was given, we will try to use the lex module
- if not lexer:
- lex = load_ply_lex()
- lexer = lex.lexer
-
- # Set up the lexer and parser objects on pslice
- pslice.lexer = lexer
- pslice.parser = self
-
- # If input was supplied, pass to lexer
- if input is not None:
- lexer.input(input)
-
- if tokenfunc is None:
- # Tokenize function
- get_token = lexer.token
- else:
- get_token = tokenfunc
-
- # Set up the state and symbol stacks
-
- statestack = [ ] # Stack of parsing states
- self.statestack = statestack
- symstack = [ ] # Stack of grammar symbols
- self.symstack = symstack
-
- pslice.stack = symstack # Put in the production
- errtoken = None # Err token
-
- # The start state is assumed to be (0,$end)
-
- statestack.append(0)
- sym = YaccSymbol()
- sym.type = "$end"
- symstack.append(sym)
- state = 0
- while 1:
- # Get the next symbol on the input. If a lookahead symbol
- # is already set, we just use that. Otherwise, we'll pull
- # the next token off of the lookaheadstack or from the lexer
-
- # --! DEBUG
- debug.debug('')
- debug.debug('State : %s', state)
- # --! DEBUG
-
- if not lookahead:
- if not lookaheadstack:
- lookahead = get_token() # Get the next token
- else:
- lookahead = lookaheadstack.pop()
- if not lookahead:
- lookahead = YaccSymbol()
- lookahead.type = "$end"
-
- # --! DEBUG
- debug.debug('Stack : %s',
- ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
- # --! DEBUG
-
- # Check the action table
- ltype = lookahead.type
- t = actions[state].get(ltype)
-
- if t is not None:
- if t > 0:
- # shift a symbol on the stack
- statestack.append(t)
- state = t
-
- # --! DEBUG
- debug.debug("Action : Shift and goto state %s", t)
- # --! DEBUG
-
- symstack.append(lookahead)
- lookahead = None
-
- # Decrease error count on successful shift
- if errorcount: errorcount -=1
- continue
-
- if t < 0:
- # reduce a symbol on the stack, emit a production
- p = prod[-t]
- pname = p.name
- plen = p.len
-
- # Get production function
- sym = YaccSymbol()
- sym.type = pname # Production name
- sym.value = None
-
- # --! DEBUG
- if plen:
- debug.info("Action : Reduce rule [%s] with %s and goto state %d", p.str, "["+",".join([format_stack_entry(_v.value) for _v in symstack[-plen:]])+"]",-t)
- else:
- debug.info("Action : Reduce rule [%s] with %s and goto state %d", p.str, [],-t)
-
- # --! DEBUG
-
- if plen:
- targ = symstack[-plen-1:]
- targ[0] = sym
-
- # --! TRACKING
- if tracking:
- t1 = targ[1]
- sym.lineno = t1.lineno
- sym.lexpos = t1.lexpos
- t1 = targ[-1]
- sym.endlineno = getattr(t1,"endlineno",t1.lineno)
- sym.endlexpos = getattr(t1,"endlexpos",t1.lexpos)
-
- # --! TRACKING
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # below as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- del symstack[-plen:]
- del statestack[-plen:]
- p.callable(pslice)
- # --! DEBUG
- debug.info("Result : %s", format_result(pslice[0]))
- # --! DEBUG
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead)
- symstack.pop()
- statestack.pop()
- state = statestack[-1]
- sym.type = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = 0
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- else:
-
- # --! TRACKING
- if tracking:
- sym.lineno = lexer.lineno
- sym.lexpos = lexer.lexpos
- # --! TRACKING
-
- targ = [ sym ]
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # above as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- p.callable(pslice)
- # --! DEBUG
- debug.info("Result : %s", format_result(pslice[0]))
- # --! DEBUG
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead)
- symstack.pop()
- statestack.pop()
- state = statestack[-1]
- sym.type = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = 0
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- if t == 0:
- n = symstack[-1]
- result = getattr(n,"value",None)
- # --! DEBUG
- debug.info("Done : Returning %s", format_result(result))
- debug.info("PLY: PARSE DEBUG END")
- # --! DEBUG
- return result
-
- if t == None:
-
- # --! DEBUG
- debug.error('Error : %s',
- ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
- # --! DEBUG
-
- # We have some kind of parsing error here. To handle
- # this, we are going to push the current token onto
- # the tokenstack and replace it with an 'error' token.
- # If there are any synchronization rules, they may
- # catch it.
- #
- # In addition to pushing the error token, we call call
- # the user defined p_error() function if this is the
- # first syntax error. This function is only called if
- # errorcount == 0.
- if errorcount == 0 or self.errorok:
- errorcount = error_count
- self.errorok = 0
- errtoken = lookahead
- if errtoken.type == "$end":
- errtoken = None # End of file!
- if self.errorfunc:
- global errok,token,restart
- errok = self.errok # Set some special functions available in error recovery
- token = get_token
- restart = self.restart
- if errtoken and not hasattr(errtoken,'lexer'):
- errtoken.lexer = lexer
- tok = self.errorfunc(errtoken)
- del errok, token, restart # Delete special functions
-
- if self.errorok:
- # User must have done some kind of panic
- # mode recovery on their own. The
- # returned token is the next lookahead
- lookahead = tok
- errtoken = None
- continue
- else:
- if errtoken:
- if hasattr(errtoken,"lineno"): lineno = lookahead.lineno
- else: lineno = 0
- if lineno:
- sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type))
- else:
- sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type)
- else:
- sys.stderr.write("yacc: Parse error in input. EOF\n")
- return
-
- else:
- errorcount = error_count
-
- # case 1: the statestack only has 1 entry on it. If we're in this state, the
- # entire parse has been rolled back and we're completely hosed. The token is
- # discarded and we just keep going.
-
- if len(statestack) <= 1 and lookahead.type != "$end":
- lookahead = None
- errtoken = None
- state = 0
- # Nuke the pushback stack
- del lookaheadstack[:]
- continue
-
- # case 2: the statestack has a couple of entries on it, but we're
- # at the end of the file. nuke the top entry and generate an error token
-
- # Start nuking entries on the stack
- if lookahead.type == "$end":
- # Whoa. We're really hosed here. Bail out
- return
-
- if lookahead.type != 'error':
- sym = symstack[-1]
- if sym.type == 'error':
- # Hmmm. Error is on top of stack, we'll just nuke input
- # symbol and continue
- lookahead = None
- continue
- t = YaccSymbol()
- t.type = 'error'
- if hasattr(lookahead,"lineno"):
- t.lineno = lookahead.lineno
- t.value = lookahead
- lookaheadstack.append(lookahead)
- lookahead = t
- else:
- symstack.pop()
- statestack.pop()
- state = statestack[-1] # Potential bug fix
-
- continue
-
- # Call an error function here
- raise RuntimeError("yacc: internal parser error!!!\n")
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # parseopt().
- #
- # Optimized version of parse() method. DO NOT EDIT THIS CODE DIRECTLY.
- # Edit the debug version above, then copy any modifications to the method
- # below while removing #--! DEBUG sections.
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
- def parseopt(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None):
- lookahead = None # Current lookahead symbol
- lookaheadstack = [ ] # Stack of lookahead symbols
- actions = self.action # Local reference to action table (to avoid lookup on self.)
- goto = self.goto # Local reference to goto table (to avoid lookup on self.)
- prod = self.productions # Local reference to production list (to avoid lookup on self.)
- pslice = YaccProduction(None) # Production object passed to grammar rules
- errorcount = 0 # Used during error recovery
-
- # If no lexer was given, we will try to use the lex module
- if not lexer:
- lex = load_ply_lex()
- lexer = lex.lexer
-
- # Set up the lexer and parser objects on pslice
- pslice.lexer = lexer
- pslice.parser = self
-
- # If input was supplied, pass to lexer
- if input is not None:
- lexer.input(input)
-
- if tokenfunc is None:
- # Tokenize function
- get_token = lexer.token
- else:
- get_token = tokenfunc
-
- # Set up the state and symbol stacks
-
- statestack = [ ] # Stack of parsing states
- self.statestack = statestack
- symstack = [ ] # Stack of grammar symbols
- self.symstack = symstack
-
- pslice.stack = symstack # Put in the production
- errtoken = None # Err token
-
- # The start state is assumed to be (0,$end)
-
- statestack.append(0)
- sym = YaccSymbol()
- sym.type = '$end'
- symstack.append(sym)
- state = 0
- while 1:
- # Get the next symbol on the input. If a lookahead symbol
- # is already set, we just use that. Otherwise, we'll pull
- # the next token off of the lookaheadstack or from the lexer
-
- if not lookahead:
- if not lookaheadstack:
- lookahead = get_token() # Get the next token
- else:
- lookahead = lookaheadstack.pop()
- if not lookahead:
- lookahead = YaccSymbol()
- lookahead.type = '$end'
-
- # Check the action table
- ltype = lookahead.type
- t = actions[state].get(ltype)
-
- if t is not None:
- if t > 0:
- # shift a symbol on the stack
- statestack.append(t)
- state = t
-
- symstack.append(lookahead)
- lookahead = None
-
- # Decrease error count on successful shift
- if errorcount: errorcount -=1
- continue
-
- if t < 0:
- # reduce a symbol on the stack, emit a production
- p = prod[-t]
- pname = p.name
- plen = p.len
-
- # Get production function
- sym = YaccSymbol()
- sym.type = pname # Production name
- sym.value = None
-
- if plen:
- targ = symstack[-plen-1:]
- targ[0] = sym
-
- # --! TRACKING
- if tracking:
- t1 = targ[1]
- sym.lineno = t1.lineno
- sym.lexpos = t1.lexpos
- t1 = targ[-1]
- sym.endlineno = getattr(t1,"endlineno",t1.lineno)
- sym.endlexpos = getattr(t1,"endlexpos",t1.lexpos)
-
- # --! TRACKING
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # below as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- del symstack[-plen:]
- del statestack[-plen:]
- p.callable(pslice)
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead)
- symstack.pop()
- statestack.pop()
- state = statestack[-1]
- sym.type = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = 0
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- else:
-
- # --! TRACKING
- if tracking:
- sym.lineno = lexer.lineno
- sym.lexpos = lexer.lexpos
- # --! TRACKING
-
- targ = [ sym ]
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # above as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- p.callable(pslice)
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead)
- symstack.pop()
- statestack.pop()
- state = statestack[-1]
- sym.type = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = 0
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- if t == 0:
- n = symstack[-1]
- return getattr(n,"value",None)
-
- if t == None:
-
- # We have some kind of parsing error here. To handle
- # this, we are going to push the current token onto
- # the tokenstack and replace it with an 'error' token.
- # If there are any synchronization rules, they may
- # catch it.
- #
- # In addition to pushing the error token, we call call
- # the user defined p_error() function if this is the
- # first syntax error. This function is only called if
- # errorcount == 0.
- if errorcount == 0 or self.errorok:
- errorcount = error_count
- self.errorok = 0
- errtoken = lookahead
- if errtoken.type == '$end':
- errtoken = None # End of file!
- if self.errorfunc:
- global errok,token,restart
- errok = self.errok # Set some special functions available in error recovery
- token = get_token
- restart = self.restart
- if errtoken and not hasattr(errtoken,'lexer'):
- errtoken.lexer = lexer
- tok = self.errorfunc(errtoken)
- del errok, token, restart # Delete special functions
-
- if self.errorok:
- # User must have done some kind of panic
- # mode recovery on their own. The
- # returned token is the next lookahead
- lookahead = tok
- errtoken = None
- continue
- else:
- if errtoken:
- if hasattr(errtoken,"lineno"): lineno = lookahead.lineno
- else: lineno = 0
- if lineno:
- sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type))
- else:
- sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type)
- else:
- sys.stderr.write("yacc: Parse error in input. EOF\n")
- return
-
- else:
- errorcount = error_count
-
- # case 1: the statestack only has 1 entry on it. If we're in this state, the
- # entire parse has been rolled back and we're completely hosed. The token is
- # discarded and we just keep going.
-
- if len(statestack) <= 1 and lookahead.type != '$end':
- lookahead = None
- errtoken = None
- state = 0
- # Nuke the pushback stack
- del lookaheadstack[:]
- continue
-
- # case 2: the statestack has a couple of entries on it, but we're
- # at the end of the file. nuke the top entry and generate an error token
-
- # Start nuking entries on the stack
- if lookahead.type == '$end':
- # Whoa. We're really hosed here. Bail out
- return
-
- if lookahead.type != 'error':
- sym = symstack[-1]
- if sym.type == 'error':
- # Hmmm. Error is on top of stack, we'll just nuke input
- # symbol and continue
- lookahead = None
- continue
- t = YaccSymbol()
- t.type = 'error'
- if hasattr(lookahead,"lineno"):
- t.lineno = lookahead.lineno
- t.value = lookahead
- lookaheadstack.append(lookahead)
- lookahead = t
- else:
- symstack.pop()
- statestack.pop()
- state = statestack[-1] # Potential bug fix
-
- continue
-
- # Call an error function here
- raise RuntimeError("yacc: internal parser error!!!\n")
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # parseopt_notrack().
- #
- # Optimized version of parseopt() with line number tracking removed.
- # DO NOT EDIT THIS CODE DIRECTLY. Copy the optimized version and remove
- # code in the #--! TRACKING sections
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- def parseopt_notrack(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None):
- lookahead = None # Current lookahead symbol
- lookaheadstack = [ ] # Stack of lookahead symbols
- actions = self.action # Local reference to action table (to avoid lookup on self.)
- goto = self.goto # Local reference to goto table (to avoid lookup on self.)
- prod = self.productions # Local reference to production list (to avoid lookup on self.)
- pslice = YaccProduction(None) # Production object passed to grammar rules
- errorcount = 0 # Used during error recovery
-
- # If no lexer was given, we will try to use the lex module
- if not lexer:
- lex = load_ply_lex()
- lexer = lex.lexer
-
- # Set up the lexer and parser objects on pslice
- pslice.lexer = lexer
- pslice.parser = self
-
- # If input was supplied, pass to lexer
- if input is not None:
- lexer.input(input)
-
- if tokenfunc is None:
- # Tokenize function
- get_token = lexer.token
- else:
- get_token = tokenfunc
-
- # Set up the state and symbol stacks
-
- statestack = [ ] # Stack of parsing states
- self.statestack = statestack
- symstack = [ ] # Stack of grammar symbols
- self.symstack = symstack
-
- pslice.stack = symstack # Put in the production
- errtoken = None # Err token
-
- # The start state is assumed to be (0,$end)
-
- statestack.append(0)
- sym = YaccSymbol()
- sym.type = '$end'
- symstack.append(sym)
- state = 0
- while 1:
- # Get the next symbol on the input. If a lookahead symbol
- # is already set, we just use that. Otherwise, we'll pull
- # the next token off of the lookaheadstack or from the lexer
-
- if not lookahead:
- if not lookaheadstack:
- lookahead = get_token() # Get the next token
- else:
- lookahead = lookaheadstack.pop()
- if not lookahead:
- lookahead = YaccSymbol()
- lookahead.type = '$end'
-
- # Check the action table
- ltype = lookahead.type
- t = actions[state].get(ltype)
-
- if t is not None:
- if t > 0:
- # shift a symbol on the stack
- statestack.append(t)
- state = t
-
- symstack.append(lookahead)
- lookahead = None
-
- # Decrease error count on successful shift
- if errorcount: errorcount -=1
- continue
-
- if t < 0:
- # reduce a symbol on the stack, emit a production
- p = prod[-t]
- pname = p.name
- plen = p.len
-
- # Get production function
- sym = YaccSymbol()
- sym.type = pname # Production name
- sym.value = None
-
- if plen:
- targ = symstack[-plen-1:]
- targ[0] = sym
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # below as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- del symstack[-plen:]
- del statestack[-plen:]
- p.callable(pslice)
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead)
- symstack.pop()
- statestack.pop()
- state = statestack[-1]
- sym.type = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = 0
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- else:
-
- targ = [ sym ]
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # above as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- p.callable(pslice)
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead)
- symstack.pop()
- statestack.pop()
- state = statestack[-1]
- sym.type = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = 0
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- if t == 0:
- n = symstack[-1]
- return getattr(n,"value",None)
-
- if t == None:
-
- # We have some kind of parsing error here. To handle
- # this, we are going to push the current token onto
- # the tokenstack and replace it with an 'error' token.
- # If there are any synchronization rules, they may
- # catch it.
- #
- # In addition to pushing the error token, we call call
- # the user defined p_error() function if this is the
- # first syntax error. This function is only called if
- # errorcount == 0.
- if errorcount == 0 or self.errorok:
- errorcount = error_count
- self.errorok = 0
- errtoken = lookahead
- if errtoken.type == '$end':
- errtoken = None # End of file!
- if self.errorfunc:
- global errok,token,restart
- errok = self.errok # Set some special functions available in error recovery
- token = get_token
- restart = self.restart
- if errtoken and not hasattr(errtoken,'lexer'):
- errtoken.lexer = lexer
- tok = self.errorfunc(errtoken)
- del errok, token, restart # Delete special functions
-
- if self.errorok:
- # User must have done some kind of panic
- # mode recovery on their own. The
- # returned token is the next lookahead
- lookahead = tok
- errtoken = None
- continue
- else:
- if errtoken:
- if hasattr(errtoken,"lineno"): lineno = lookahead.lineno
- else: lineno = 0
- if lineno:
- sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type))
- else:
- sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type)
- else:
- sys.stderr.write("yacc: Parse error in input. EOF\n")
- return
-
- else:
- errorcount = error_count
-
- # case 1: the statestack only has 1 entry on it. If we're in this state, the
- # entire parse has been rolled back and we're completely hosed. The token is
- # discarded and we just keep going.
-
- if len(statestack) <= 1 and lookahead.type != '$end':
- lookahead = None
- errtoken = None
- state = 0
- # Nuke the pushback stack
- del lookaheadstack[:]
- continue
-
- # case 2: the statestack has a couple of entries on it, but we're
- # at the end of the file. nuke the top entry and generate an error token
-
- # Start nuking entries on the stack
- if lookahead.type == '$end':
- # Whoa. We're really hosed here. Bail out
- return
-
- if lookahead.type != 'error':
- sym = symstack[-1]
- if sym.type == 'error':
- # Hmmm. Error is on top of stack, we'll just nuke input
- # symbol and continue
- lookahead = None
- continue
- t = YaccSymbol()
- t.type = 'error'
- if hasattr(lookahead,"lineno"):
- t.lineno = lookahead.lineno
- t.value = lookahead
- lookaheadstack.append(lookahead)
- lookahead = t
- else:
- symstack.pop()
- statestack.pop()
- state = statestack[-1] # Potential bug fix
-
- continue
-
- # Call an error function here
- raise RuntimeError("yacc: internal parser error!!!\n")
-
-# -----------------------------------------------------------------------------
-# === Grammar Representation ===
-#
-# The following functions, classes, and variables are used to represent and
-# manipulate the rules that make up a grammar.
-# -----------------------------------------------------------------------------
-
-import re
-
-# regex matching identifiers
-_is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$')
-
-# -----------------------------------------------------------------------------
-# class Production:
-#
-# This class stores the raw information about a single production or grammar rule.
-# A grammar rule refers to a specification such as this:
-#
-# expr : expr PLUS term
-#
-# Here are the basic attributes defined on all productions
-#
-# name - Name of the production. For example 'expr'
-# prod - A list of symbols on the right side ['expr','PLUS','term']
-# prec - Production precedence level
-# number - Production number.
-# func - Function that executes on reduce
-# file - File where production function is defined
-# lineno - Line number where production function is defined
-#
-# The following attributes are defined or optional.
-#
-# len - Length of the production (number of symbols on right hand side)
-# usyms - Set of unique symbols found in the production
-# -----------------------------------------------------------------------------
-
-class Production(object):
- reduced = 0
- def __init__(self,number,name,prod,precedence=('right',0),func=None,file='',line=0):
- self.name = name
- self.prod = tuple(prod)
- self.number = number
- self.func = func
- self.callable = None
- self.file = file
- self.line = line
- self.prec = precedence
-
- # Internal settings used during table construction
-
- self.len = len(self.prod) # Length of the production
-
- # Create a list of unique production symbols used in the production
- self.usyms = [ ]
- for s in self.prod:
- if s not in self.usyms:
- self.usyms.append(s)
-
- # List of all LR items for the production
- self.lr_items = []
- self.lr_next = None
-
- # Create a string representation
- if self.prod:
- self.str = "%s -> %s" % (self.name," ".join(self.prod))
- else:
- self.str = "%s -> <empty>" % self.name
-
- def __str__(self):
- return self.str
-
- def __repr__(self):
- return "Production("+str(self)+")"
-
- def __len__(self):
- return len(self.prod)
-
- def __nonzero__(self):
- return 1
-
- def __getitem__(self,index):
- return self.prod[index]
-
- # Return the nth lr_item from the production (or None if at the end)
- def lr_item(self,n):
- if n > len(self.prod): return None
- p = LRItem(self,n)
-
- # Precompute the list of productions immediately following. Hack. Remove later
- try:
- p.lr_after = Prodnames[p.prod[n+1]]
- except (IndexError,KeyError):
- p.lr_after = []
- try:
- p.lr_before = p.prod[n-1]
- except IndexError:
- p.lr_before = None
-
- return p
-
- # Bind the production function name to a callable
- def bind(self,pdict):
- if self.func:
- self.callable = pdict[self.func]
-
-# This class serves as a minimal standin for Production objects when
-# reading table data from files. It only contains information
-# actually used by the LR parsing engine, plus some additional
-# debugging information.
-class MiniProduction(object):
- def __init__(self,str,name,len,func,file,line):
- self.name = name
- self.len = len
- self.func = func
- self.callable = None
- self.file = file
- self.line = line
- self.str = str
- def __str__(self):
- return self.str
- def __repr__(self):
- return "MiniProduction(%s)" % self.str
-
- # Bind the production function name to a callable
- def bind(self,pdict):
- if self.func:
- self.callable = pdict[self.func]
-
-
-# -----------------------------------------------------------------------------
-# class LRItem
-#
-# This class represents a specific stage of parsing a production rule. For
-# example:
-#
-# expr : expr . PLUS term
-#
-# In the above, the "." represents the current location of the parse. Here
-# basic attributes:
-#
-# name - Name of the production. For example 'expr'
-# prod - A list of symbols on the right side ['expr','.', 'PLUS','term']
-# number - Production number.
-#
-# lr_next Next LR item. Example, if we are ' expr -> expr . PLUS term'
-# then lr_next refers to 'expr -> expr PLUS . term'
-# lr_index - LR item index (location of the ".") in the prod list.
-# lookaheads - LALR lookahead symbols for this item
-# len - Length of the production (number of symbols on right hand side)
-# lr_after - List of all productions that immediately follow
-# lr_before - Grammar symbol immediately before
-# -----------------------------------------------------------------------------
-
-class LRItem(object):
- def __init__(self,p,n):
- self.name = p.name
- self.prod = list(p.prod)
- self.number = p.number
- self.lr_index = n
- self.lookaheads = { }
- self.prod.insert(n,".")
- self.prod = tuple(self.prod)
- self.len = len(self.prod)
- self.usyms = p.usyms
-
- def __str__(self):
- if self.prod:
- s = "%s -> %s" % (self.name," ".join(self.prod))
- else:
- s = "%s -> <empty>" % self.name
- return s
-
- def __repr__(self):
- return "LRItem("+str(self)+")"
-
-# -----------------------------------------------------------------------------
-# rightmost_terminal()
-#
-# Return the rightmost terminal from a list of symbols. Used in add_production()
-# -----------------------------------------------------------------------------
-def rightmost_terminal(symbols, terminals):
- i = len(symbols) - 1
- while i >= 0:
- if symbols[i] in terminals:
- return symbols[i]
- i -= 1
- return None
-
-# -----------------------------------------------------------------------------
-# === GRAMMAR CLASS ===
-#
-# The following class represents the contents of the specified grammar along
-# with various computed properties such as first sets, follow sets, LR items, etc.
-# This data is used for critical parts of the table generation process later.
-# -----------------------------------------------------------------------------
-
-class GrammarError(YaccError): pass
-
-class Grammar(object):
- def __init__(self,terminals):
- self.Productions = [None] # A list of all of the productions. The first
- # entry is always reserved for the purpose of
- # building an augmented grammar
-
- self.Prodnames = { } # A dictionary mapping the names of nonterminals to a list of all
- # productions of that nonterminal.
-
- self.Prodmap = { } # A dictionary that is only used to detect duplicate
- # productions.
-
- self.Terminals = { } # A dictionary mapping the names of terminal symbols to a
- # list of the rules where they are used.
-
- for term in terminals:
- self.Terminals[term] = []
-
- self.Terminals['error'] = []
-
- self.Nonterminals = { } # A dictionary mapping names of nonterminals to a list
- # of rule numbers where they are used.
-
- self.First = { } # A dictionary of precomputed FIRST(x) symbols
-
- self.Follow = { } # A dictionary of precomputed FOLLOW(x) symbols
-
- self.Precedence = { } # Precedence rules for each terminal. Contains tuples of the
- # form ('right',level) or ('nonassoc', level) or ('left',level)
-
- self.UsedPrecedence = { } # Precedence rules that were actually used by the grammer.
- # This is only used to provide error checking and to generate
- # a warning about unused precedence rules.
-
- self.Start = None # Starting symbol for the grammar
-
-
- def __len__(self):
- return len(self.Productions)
-
- def __getitem__(self,index):
- return self.Productions[index]
-
- # -----------------------------------------------------------------------------
- # set_precedence()
- #
- # Sets the precedence for a given terminal. assoc is the associativity such as
- # 'left','right', or 'nonassoc'. level is a numeric level.
- #
- # -----------------------------------------------------------------------------
-
- def set_precedence(self,term,assoc,level):
- assert self.Productions == [None],"Must call set_precedence() before add_production()"
- if term in self.Precedence:
- raise GrammarError("Precedence already specified for terminal '%s'" % term)
- if assoc not in ['left','right','nonassoc']:
- raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'")
- self.Precedence[term] = (assoc,level)
-
- # -----------------------------------------------------------------------------
- # add_production()
- #
- # Given an action function, this function assembles a production rule and
- # computes its precedence level.
- #
- # The production rule is supplied as a list of symbols. For example,
- # a rule such as 'expr : expr PLUS term' has a production name of 'expr' and
- # symbols ['expr','PLUS','term'].
- #
- # Precedence is determined by the precedence of the right-most non-terminal
- # or the precedence of a terminal specified by %prec.
- #
- # A variety of error checks are performed to make sure production symbols
- # are valid and that %prec is used correctly.
- # -----------------------------------------------------------------------------
-
- def add_production(self,prodname,syms,func=None,file='',line=0):
-
- if prodname in self.Terminals:
- raise GrammarError("%s:%d: Illegal rule name '%s'. Already defined as a token" % (file,line,prodname))
- if prodname == 'error':
- raise GrammarError("%s:%d: Illegal rule name '%s'. error is a reserved word" % (file,line,prodname))
- if not _is_identifier.match(prodname):
- raise GrammarError("%s:%d: Illegal rule name '%s'" % (file,line,prodname))
-
- # Look for literal tokens
- for n,s in enumerate(syms):
- if s[0] in "'\"":
- try:
- c = eval(s)
- if (len(c) > 1):
- raise GrammarError("%s:%d: Literal token %s in rule '%s' may only be a single character" % (file,line,s, prodname))
- if not c in self.Terminals:
- self.Terminals[c] = []
- syms[n] = c
- continue
- except SyntaxError:
- pass
- if not _is_identifier.match(s) and s != '%prec':
- raise GrammarError("%s:%d: Illegal name '%s' in rule '%s'" % (file,line,s, prodname))
-
- # Determine the precedence level
- if '%prec' in syms:
- if syms[-1] == '%prec':
- raise GrammarError("%s:%d: Syntax error. Nothing follows %%prec" % (file,line))
- if syms[-2] != '%prec':
- raise GrammarError("%s:%d: Syntax error. %%prec can only appear at the end of a grammar rule" % (file,line))
- precname = syms[-1]
- prodprec = self.Precedence.get(precname,None)
- if not prodprec:
- raise GrammarError("%s:%d: Nothing known about the precedence of '%s'" % (file,line,precname))
- else:
- self.UsedPrecedence[precname] = 1
- del syms[-2:] # Drop %prec from the rule
- else:
- # If no %prec, precedence is determined by the rightmost terminal symbol
- precname = rightmost_terminal(syms,self.Terminals)
- prodprec = self.Precedence.get(precname,('right',0))
-
- # See if the rule is already in the rulemap
- map = "%s -> %s" % (prodname,syms)
- if map in self.Prodmap:
- m = self.Prodmap[map]
- raise GrammarError("%s:%d: Duplicate rule %s. " % (file,line, m) +
- "Previous definition at %s:%d" % (m.file, m.line))
-
- # From this point on, everything is valid. Create a new Production instance
- pnumber = len(self.Productions)
- if not prodname in self.Nonterminals:
- self.Nonterminals[prodname] = [ ]
-
- # Add the production number to Terminals and Nonterminals
- for t in syms:
- if t in self.Terminals:
- self.Terminals[t].append(pnumber)
- else:
- if not t in self.Nonterminals:
- self.Nonterminals[t] = [ ]
- self.Nonterminals[t].append(pnumber)
-
- # Create a production and add it to the list of productions
- p = Production(pnumber,prodname,syms,prodprec,func,file,line)
- self.Productions.append(p)
- self.Prodmap[map] = p
-
- # Add to the global productions list
- try:
- self.Prodnames[prodname].append(p)
- except KeyError:
- self.Prodnames[prodname] = [ p ]
- return 0
-
- # -----------------------------------------------------------------------------
- # set_start()
- #
- # Sets the starting symbol and creates the augmented grammar. Production
- # rule 0 is S' -> start where start is the start symbol.
- # -----------------------------------------------------------------------------
-
- def set_start(self,start=None):
- if not start:
- start = self.Productions[1].name
- if start not in self.Nonterminals:
- raise GrammarError("start symbol %s undefined" % start)
- self.Productions[0] = Production(0,"S'",[start])
- self.Nonterminals[start].append(0)
- self.Start = start
-
- # -----------------------------------------------------------------------------
- # find_unreachable()
- #
- # Find all of the nonterminal symbols that can't be reached from the starting
- # symbol. Returns a list of nonterminals that can't be reached.
- # -----------------------------------------------------------------------------
-
- def find_unreachable(self):
-
- # Mark all symbols that are reachable from a symbol s
- def mark_reachable_from(s):
- if reachable[s]:
- # We've already reached symbol s.
- return
- reachable[s] = 1
- for p in self.Prodnames.get(s,[]):
- for r in p.prod:
- mark_reachable_from(r)
-
- reachable = { }
- for s in list(self.Terminals) + list(self.Nonterminals):
- reachable[s] = 0
-
- mark_reachable_from( self.Productions[0].prod[0] )
-
- return [s for s in list(self.Nonterminals)
- if not reachable[s]]
-
- # -----------------------------------------------------------------------------
- # infinite_cycles()
- #
- # This function looks at the various parsing rules and tries to detect
- # infinite recursion cycles (grammar rules where there is no possible way
- # to derive a string of only terminals).
- # -----------------------------------------------------------------------------
-
- def infinite_cycles(self):
- terminates = {}
-
- # Terminals:
- for t in self.Terminals:
- terminates[t] = 1
-
- terminates['$end'] = 1
-
- # Nonterminals:
-
- # Initialize to false:
- for n in self.Nonterminals:
- terminates[n] = 0
-
- # Then propagate termination until no change:
- while 1:
- some_change = 0
- for (n,pl) in self.Prodnames.items():
- # Nonterminal n terminates iff any of its productions terminates.
- for p in pl:
- # Production p terminates iff all of its rhs symbols terminate.
- for s in p.prod:
- if not terminates[s]:
- # The symbol s does not terminate,
- # so production p does not terminate.
- p_terminates = 0
- break
- else:
- # didn't break from the loop,
- # so every symbol s terminates
- # so production p terminates.
- p_terminates = 1
-
- if p_terminates:
- # symbol n terminates!
- if not terminates[n]:
- terminates[n] = 1
- some_change = 1
- # Don't need to consider any more productions for this n.
- break
-
- if not some_change:
- break
-
- infinite = []
- for (s,term) in terminates.items():
- if not term:
- if not s in self.Prodnames and not s in self.Terminals and s != 'error':
- # s is used-but-not-defined, and we've already warned of that,
- # so it would be overkill to say that it's also non-terminating.
- pass
- else:
- infinite.append(s)
-
- return infinite
-
-
- # -----------------------------------------------------------------------------
- # undefined_symbols()
- #
- # Find all symbols that were used the grammar, but not defined as tokens or
- # grammar rules. Returns a list of tuples (sym, prod) where sym in the symbol
- # and prod is the production where the symbol was used.
- # -----------------------------------------------------------------------------
- def undefined_symbols(self):
- result = []
- for p in self.Productions:
- if not p: continue
-
- for s in p.prod:
- if not s in self.Prodnames and not s in self.Terminals and s != 'error':
- result.append((s,p))
- return result
-
- # -----------------------------------------------------------------------------
- # unused_terminals()
- #
- # Find all terminals that were defined, but not used by the grammar. Returns
- # a list of all symbols.
- # -----------------------------------------------------------------------------
- def unused_terminals(self):
- unused_tok = []
- for s,v in self.Terminals.items():
- if s != 'error' and not v:
- unused_tok.append(s)
-
- return unused_tok
-
- # ------------------------------------------------------------------------------
- # unused_rules()
- #
- # Find all grammar rules that were defined, but not used (maybe not reachable)
- # Returns a list of productions.
- # ------------------------------------------------------------------------------
-
- def unused_rules(self):
- unused_prod = []
- for s,v in self.Nonterminals.items():
- if not v:
- p = self.Prodnames[s][0]
- unused_prod.append(p)
- return unused_prod
-
- # -----------------------------------------------------------------------------
- # unused_precedence()
- #
- # Returns a list of tuples (term,precedence) corresponding to precedence
- # rules that were never used by the grammar. term is the name of the terminal
- # on which precedence was applied and precedence is a string such as 'left' or
- # 'right' corresponding to the type of precedence.
- # -----------------------------------------------------------------------------
-
- def unused_precedence(self):
- unused = []
- for termname in self.Precedence:
- if not (termname in self.Terminals or termname in self.UsedPrecedence):
- unused.append((termname,self.Precedence[termname][0]))
-
- return unused
-
- # -------------------------------------------------------------------------
- # _first()
- #
- # Compute the value of FIRST1(beta) where beta is a tuple of symbols.
- #
- # During execution of compute_first1, the result may be incomplete.
- # Afterward (e.g., when called from compute_follow()), it will be complete.
- # -------------------------------------------------------------------------
- def _first(self,beta):
-
- # We are computing First(x1,x2,x3,...,xn)
- result = [ ]
- for x in beta:
- x_produces_empty = 0
-
- # Add all the non-<empty> symbols of First[x] to the result.
- for f in self.First[x]:
- if f == '<empty>':
- x_produces_empty = 1
- else:
- if f not in result: result.append(f)
-
- if x_produces_empty:
- # We have to consider the next x in beta,
- # i.e. stay in the loop.
- pass
- else:
- # We don't have to consider any further symbols in beta.
- break
- else:
- # There was no 'break' from the loop,
- # so x_produces_empty was true for all x in beta,
- # so beta produces empty as well.
- result.append('<empty>')
-
- return result
-
- # -------------------------------------------------------------------------
- # compute_first()
- #
- # Compute the value of FIRST1(X) for all symbols
- # -------------------------------------------------------------------------
- def compute_first(self):
- if self.First:
- return self.First
-
- # Terminals:
- for t in self.Terminals:
- self.First[t] = [t]
-
- self.First['$end'] = ['$end']
-
- # Nonterminals:
-
- # Initialize to the empty set:
- for n in self.Nonterminals:
- self.First[n] = []
-
- # Then propagate symbols until no change:
- while 1:
- some_change = 0
- for n in self.Nonterminals:
- for p in self.Prodnames[n]:
- for f in self._first(p.prod):
- if f not in self.First[n]:
- self.First[n].append( f )
- some_change = 1
- if not some_change:
- break
-
- return self.First
-
- # ---------------------------------------------------------------------
- # compute_follow()
- #
- # Computes all of the follow sets for every non-terminal symbol. The
- # follow set is the set of all symbols that might follow a given
- # non-terminal. See the Dragon book, 2nd Ed. p. 189.
- # ---------------------------------------------------------------------
- def compute_follow(self,start=None):
- # If already computed, return the result
- if self.Follow:
- return self.Follow
-
- # If first sets not computed yet, do that first.
- if not self.First:
- self.compute_first()
-
- # Add '$end' to the follow list of the start symbol
- for k in self.Nonterminals:
- self.Follow[k] = [ ]
-
- if not start:
- start = self.Productions[1].name
-
- self.Follow[start] = [ '$end' ]
-
- while 1:
- didadd = 0
- for p in self.Productions[1:]:
- # Here is the production set
- for i in range(len(p.prod)):
- B = p.prod[i]
- if B in self.Nonterminals:
- # Okay. We got a non-terminal in a production
- fst = self._first(p.prod[i+1:])
- hasempty = 0
- for f in fst:
- if f != '<empty>' and f not in self.Follow[B]:
- self.Follow[B].append(f)
- didadd = 1
- if f == '<empty>':
- hasempty = 1
- if hasempty or i == (len(p.prod)-1):
- # Add elements of follow(a) to follow(b)
- for f in self.Follow[p.name]:
- if f not in self.Follow[B]:
- self.Follow[B].append(f)
- didadd = 1
- if not didadd: break
- return self.Follow
-
-
- # -----------------------------------------------------------------------------
- # build_lritems()
- #
- # This function walks the list of productions and builds a complete set of the
- # LR items. The LR items are stored in two ways: First, they are uniquely
- # numbered and placed in the list _lritems. Second, a linked list of LR items
- # is built for each production. For example:
- #
- # E -> E PLUS E
- #
- # Creates the list
- #
- # [E -> . E PLUS E, E -> E . PLUS E, E -> E PLUS . E, E -> E PLUS E . ]
- # -----------------------------------------------------------------------------
-
- def build_lritems(self):
- for p in self.Productions:
- lastlri = p
- i = 0
- lr_items = []
- while 1:
- if i > len(p):
- lri = None
- else:
- lri = LRItem(p,i)
- # Precompute the list of productions immediately following
- try:
- lri.lr_after = self.Prodnames[lri.prod[i+1]]
- except (IndexError,KeyError):
- lri.lr_after = []
- try:
- lri.lr_before = lri.prod[i-1]
- except IndexError:
- lri.lr_before = None
-
- lastlri.lr_next = lri
- if not lri: break
- lr_items.append(lri)
- lastlri = lri
- i += 1
- p.lr_items = lr_items
-
-# -----------------------------------------------------------------------------
-# == Class LRTable ==
-#
-# This basic class represents a basic table of LR parsing information.
-# Methods for generating the tables are not defined here. They are defined
-# in the derived class LRGeneratedTable.
-# -----------------------------------------------------------------------------
-
-class VersionError(YaccError): pass
-
-class LRTable(object):
- def __init__(self):
- self.lr_action = None
- self.lr_goto = None
- self.lr_productions = None
- self.lr_method = None
-
- def read_table(self,module):
- if isinstance(module,types.ModuleType):
- parsetab = module
- else:
- if sys.version_info[0] < 3:
- exec("import %s as parsetab" % module)
- else:
- env = { }
- exec("import %s as parsetab" % module, env, env)
- parsetab = env['parsetab']
-
- if parsetab._tabversion != __tabversion__:
- raise VersionError("yacc table file version is out of date")
-
- self.lr_action = parsetab._lr_action
- self.lr_goto = parsetab._lr_goto
-
- self.lr_productions = []
- for p in parsetab._lr_productions:
- self.lr_productions.append(MiniProduction(*p))
-
- self.lr_method = parsetab._lr_method
- return parsetab._lr_signature
-
- def read_pickle(self,filename):
- try:
- import cPickle as pickle
- except ImportError:
- import pickle
-
- in_f = open(filename,"rb")
-
- tabversion = pickle.load(in_f)
- if tabversion != __tabversion__:
- raise VersionError("yacc table file version is out of date")
- self.lr_method = pickle.load(in_f)
- signature = pickle.load(in_f)
- self.lr_action = pickle.load(in_f)
- self.lr_goto = pickle.load(in_f)
- productions = pickle.load(in_f)
-
- self.lr_productions = []
- for p in productions:
- self.lr_productions.append(MiniProduction(*p))
-
- in_f.close()
- return signature
-
- # Bind all production function names to callable objects in pdict
- def bind_callables(self,pdict):
- for p in self.lr_productions:
- p.bind(pdict)
-
-# -----------------------------------------------------------------------------
-# === LR Generator ===
-#
-# The following classes and functions are used to generate LR parsing tables on
-# a grammar.
-# -----------------------------------------------------------------------------
-
-# -----------------------------------------------------------------------------
-# digraph()
-# traverse()
-#
-# The following two functions are used to compute set valued functions
-# of the form:
-#
-# F(x) = F'(x) U U{F(y) | x R y}
-#
-# This is used to compute the values of Read() sets as well as FOLLOW sets
-# in LALR(1) generation.
-#
-# Inputs: X - An input set
-# R - A relation
-# FP - Set-valued function
-# ------------------------------------------------------------------------------
-
-def digraph(X,R,FP):
- N = { }
- for x in X:
- N[x] = 0
- stack = []
- F = { }
- for x in X:
- if N[x] == 0: traverse(x,N,stack,F,X,R,FP)
- return F
-
-def traverse(x,N,stack,F,X,R,FP):
- stack.append(x)
- d = len(stack)
- N[x] = d
- F[x] = FP(x) # F(X) <- F'(x)
-
- rel = R(x) # Get y's related to x
- for y in rel:
- if N[y] == 0:
- traverse(y,N,stack,F,X,R,FP)
- N[x] = min(N[x],N[y])
- for a in F.get(y,[]):
- if a not in F[x]: F[x].append(a)
- if N[x] == d:
- N[stack[-1]] = MAXINT
- F[stack[-1]] = F[x]
- element = stack.pop()
- while element != x:
- N[stack[-1]] = MAXINT
- F[stack[-1]] = F[x]
- element = stack.pop()
-
-class LALRError(YaccError): pass
-
-# -----------------------------------------------------------------------------
-# == LRGeneratedTable ==
-#
-# This class implements the LR table generation algorithm. There are no
-# public methods except for write()
-# -----------------------------------------------------------------------------
-
-class LRGeneratedTable(LRTable):
- def __init__(self,grammar,method='LALR',log=None):
- if method not in ['SLR','LALR']:
- raise LALRError("Unsupported method %s" % method)
-
- self.grammar = grammar
- self.lr_method = method
-
- # Set up the logger
- if not log:
- log = NullLogger()
- self.log = log
-
- # Internal attributes
- self.lr_action = {} # Action table
- self.lr_goto = {} # Goto table
- self.lr_productions = grammar.Productions # Copy of grammar Production array
- self.lr_goto_cache = {} # Cache of computed gotos
- self.lr0_cidhash = {} # Cache of closures
-
- self._add_count = 0 # Internal counter used to detect cycles
-
- # Diagonistic information filled in by the table generator
- self.sr_conflict = 0
- self.rr_conflict = 0
- self.conflicts = [] # List of conflicts
-
- self.sr_conflicts = []
- self.rr_conflicts = []
-
- # Build the tables
- self.grammar.build_lritems()
- self.grammar.compute_first()
- self.grammar.compute_follow()
- self.lr_parse_table()
-
- # Compute the LR(0) closure operation on I, where I is a set of LR(0) items.
-
- def lr0_closure(self,I):
- self._add_count += 1
-
- # Add everything in I to J
- J = I[:]
- didadd = 1
- while didadd:
- didadd = 0
- for j in J:
- for x in j.lr_after:
- if getattr(x,"lr0_added",0) == self._add_count: continue
- # Add B --> .G to J
- J.append(x.lr_next)
- x.lr0_added = self._add_count
- didadd = 1
-
- return J
-
- # Compute the LR(0) goto function goto(I,X) where I is a set
- # of LR(0) items and X is a grammar symbol. This function is written
- # in a way that guarantees uniqueness of the generated goto sets
- # (i.e. the same goto set will never be returned as two different Python
- # objects). With uniqueness, we can later do fast set comparisons using
- # id(obj) instead of element-wise comparison.
-
- def lr0_goto(self,I,x):
- # First we look for a previously cached entry
- g = self.lr_goto_cache.get((id(I),x),None)
- if g: return g
-
- # Now we generate the goto set in a way that guarantees uniqueness
- # of the result
-
- s = self.lr_goto_cache.get(x,None)
- if not s:
- s = { }
- self.lr_goto_cache[x] = s
-
- gs = [ ]
- for p in I:
- n = p.lr_next
- if n and n.lr_before == x:
- s1 = s.get(id(n),None)
- if not s1:
- s1 = { }
- s[id(n)] = s1
- gs.append(n)
- s = s1
- g = s.get('$end',None)
- if not g:
- if gs:
- g = self.lr0_closure(gs)
- s['$end'] = g
- else:
- s['$end'] = gs
- self.lr_goto_cache[(id(I),x)] = g
- return g
-
- # Compute the LR(0) sets of item function
- def lr0_items(self):
-
- C = [ self.lr0_closure([self.grammar.Productions[0].lr_next]) ]
- i = 0
- for I in C:
- self.lr0_cidhash[id(I)] = i
- i += 1
-
- # Loop over the items in C and each grammar symbols
- i = 0
- while i < len(C):
- I = C[i]
- i += 1
-
- # Collect all of the symbols that could possibly be in the goto(I,X) sets
- asyms = { }
- for ii in I:
- for s in ii.usyms:
- asyms[s] = None
-
- for x in asyms:
- g = self.lr0_goto(I,x)
- if not g: continue
- if id(g) in self.lr0_cidhash: continue
- self.lr0_cidhash[id(g)] = len(C)
- C.append(g)
-
- return C
-
- # -----------------------------------------------------------------------------
- # ==== LALR(1) Parsing ====
- #
- # LALR(1) parsing is almost exactly the same as SLR except that instead of
- # relying upon Follow() sets when performing reductions, a more selective
- # lookahead set that incorporates the state of the LR(0) machine is utilized.
- # Thus, we mainly just have to focus on calculating the lookahead sets.
- #
- # The method used here is due to DeRemer and Pennelo (1982).
- #
- # DeRemer, F. L., and T. J. Pennelo: "Efficient Computation of LALR(1)
- # Lookahead Sets", ACM Transactions on Programming Languages and Systems,
- # Vol. 4, No. 4, Oct. 1982, pp. 615-649
- #
- # Further details can also be found in:
- #
- # J. Tremblay and P. Sorenson, "The Theory and Practice of Compiler Writing",
- # McGraw-Hill Book Company, (1985).
- #
- # -----------------------------------------------------------------------------
-
- # -----------------------------------------------------------------------------
- # compute_nullable_nonterminals()
- #
- # Creates a dictionary containing all of the non-terminals that might produce
- # an empty production.
- # -----------------------------------------------------------------------------
-
- def compute_nullable_nonterminals(self):
- nullable = {}
- num_nullable = 0
- while 1:
- for p in self.grammar.Productions[1:]:
- if p.len == 0:
- nullable[p.name] = 1
- continue
- for t in p.prod:
- if not t in nullable: break
- else:
- nullable[p.name] = 1
- if len(nullable) == num_nullable: break
- num_nullable = len(nullable)
- return nullable
-
- # -----------------------------------------------------------------------------
- # find_nonterminal_trans(C)
- #
- # Given a set of LR(0) items, this functions finds all of the non-terminal
- # transitions. These are transitions in which a dot appears immediately before
- # a non-terminal. Returns a list of tuples of the form (state,N) where state
- # is the state number and N is the nonterminal symbol.
- #
- # The input C is the set of LR(0) items.
- # -----------------------------------------------------------------------------
-
- def find_nonterminal_transitions(self,C):
- trans = []
- for state in range(len(C)):
- for p in C[state]:
- if p.lr_index < p.len - 1:
- t = (state,p.prod[p.lr_index+1])
- if t[1] in self.grammar.Nonterminals:
- if t not in trans: trans.append(t)
- state = state + 1
- return trans
-
- # -----------------------------------------------------------------------------
- # dr_relation()
- #
- # Computes the DR(p,A) relationships for non-terminal transitions. The input
- # is a tuple (state,N) where state is a number and N is a nonterminal symbol.
- #
- # Returns a list of terminals.
- # -----------------------------------------------------------------------------
-
- def dr_relation(self,C,trans,nullable):
- dr_set = { }
- state,N = trans
- terms = []
-
- g = self.lr0_goto(C[state],N)
- for p in g:
- if p.lr_index < p.len - 1:
- a = p.prod[p.lr_index+1]
- if a in self.grammar.Terminals:
- if a not in terms: terms.append(a)
-
- # This extra bit is to handle the start state
- if state == 0 and N == self.grammar.Productions[0].prod[0]:
- terms.append('$end')
-
- return terms
-
- # -----------------------------------------------------------------------------
- # reads_relation()
- #
- # Computes the READS() relation (p,A) READS (t,C).
- # -----------------------------------------------------------------------------
-
- def reads_relation(self,C, trans, empty):
- # Look for empty transitions
- rel = []
- state, N = trans
-
- g = self.lr0_goto(C[state],N)
- j = self.lr0_cidhash.get(id(g),-1)
- for p in g:
- if p.lr_index < p.len - 1:
- a = p.prod[p.lr_index + 1]
- if a in empty:
- rel.append((j,a))
-
- return rel
-
- # -----------------------------------------------------------------------------
- # compute_lookback_includes()
- #
- # Determines the lookback and includes relations
- #
- # LOOKBACK:
- #
- # This relation is determined by running the LR(0) state machine forward.
- # For example, starting with a production "N : . A B C", we run it forward
- # to obtain "N : A B C ." We then build a relationship between this final
- # state and the starting state. These relationships are stored in a dictionary
- # lookdict.
- #
- # INCLUDES:
- #
- # Computes the INCLUDE() relation (p,A) INCLUDES (p',B).
- #
- # This relation is used to determine non-terminal transitions that occur
- # inside of other non-terminal transition states. (p,A) INCLUDES (p', B)
- # if the following holds:
- #
- # B -> LAT, where T -> epsilon and p' -L-> p
- #
- # L is essentially a prefix (which may be empty), T is a suffix that must be
- # able to derive an empty string. State p' must lead to state p with the string L.
- #
- # -----------------------------------------------------------------------------
-
- def compute_lookback_includes(self,C,trans,nullable):
-
- lookdict = {} # Dictionary of lookback relations
- includedict = {} # Dictionary of include relations
-
- # Make a dictionary of non-terminal transitions
- dtrans = {}
- for t in trans:
- dtrans[t] = 1
-
- # Loop over all transitions and compute lookbacks and includes
- for state,N in trans:
- lookb = []
- includes = []
- for p in C[state]:
- if p.name != N: continue
-
- # Okay, we have a name match. We now follow the production all the way
- # through the state machine until we get the . on the right hand side
-
- lr_index = p.lr_index
- j = state
- while lr_index < p.len - 1:
- lr_index = lr_index + 1
- t = p.prod[lr_index]
-
- # Check to see if this symbol and state are a non-terminal transition
- if (j,t) in dtrans:
- # Yes. Okay, there is some chance that this is an includes relation
- # the only way to know for certain is whether the rest of the
- # production derives empty
-
- li = lr_index + 1
- while li < p.len:
- if p.prod[li] in self.grammar.Terminals: break # No forget it
- if not p.prod[li] in nullable: break
- li = li + 1
- else:
- # Appears to be a relation between (j,t) and (state,N)
- includes.append((j,t))
-
- g = self.lr0_goto(C[j],t) # Go to next set
- j = self.lr0_cidhash.get(id(g),-1) # Go to next state
-
- # When we get here, j is the final state, now we have to locate the production
- for r in C[j]:
- if r.name != p.name: continue
- if r.len != p.len: continue
- i = 0
- # This look is comparing a production ". A B C" with "A B C ."
- while i < r.lr_index:
- if r.prod[i] != p.prod[i+1]: break
- i = i + 1
- else:
- lookb.append((j,r))
- for i in includes:
- if not i in includedict: includedict[i] = []
- includedict[i].append((state,N))
- lookdict[(state,N)] = lookb
-
- return lookdict,includedict
-
- # -----------------------------------------------------------------------------
- # compute_read_sets()
- #
- # Given a set of LR(0) items, this function computes the read sets.
- #
- # Inputs: C = Set of LR(0) items
- # ntrans = Set of nonterminal transitions
- # nullable = Set of empty transitions
- #
- # Returns a set containing the read sets
- # -----------------------------------------------------------------------------
-
- def compute_read_sets(self,C, ntrans, nullable):
- FP = lambda x: self.dr_relation(C,x,nullable)
- R = lambda x: self.reads_relation(C,x,nullable)
- F = digraph(ntrans,R,FP)
- return F
-
- # -----------------------------------------------------------------------------
- # compute_follow_sets()
- #
- # Given a set of LR(0) items, a set of non-terminal transitions, a readset,
- # and an include set, this function computes the follow sets
- #
- # Follow(p,A) = Read(p,A) U U {Follow(p',B) | (p,A) INCLUDES (p',B)}
- #
- # Inputs:
- # ntrans = Set of nonterminal transitions
- # readsets = Readset (previously computed)
- # inclsets = Include sets (previously computed)
- #
- # Returns a set containing the follow sets
- # -----------------------------------------------------------------------------
-
- def compute_follow_sets(self,ntrans,readsets,inclsets):
- FP = lambda x: readsets[x]
- R = lambda x: inclsets.get(x,[])
- F = digraph(ntrans,R,FP)
- return F
-
- # -----------------------------------------------------------------------------
- # add_lookaheads()
- #
- # Attaches the lookahead symbols to grammar rules.
- #
- # Inputs: lookbacks - Set of lookback relations
- # followset - Computed follow set
- #
- # This function directly attaches the lookaheads to productions contained
- # in the lookbacks set
- # -----------------------------------------------------------------------------
-
- def add_lookaheads(self,lookbacks,followset):
- for trans,lb in lookbacks.items():
- # Loop over productions in lookback
- for state,p in lb:
- if not state in p.lookaheads:
- p.lookaheads[state] = []
- f = followset.get(trans,[])
- for a in f:
- if a not in p.lookaheads[state]: p.lookaheads[state].append(a)
-
- # -----------------------------------------------------------------------------
- # add_lalr_lookaheads()
- #
- # This function does all of the work of adding lookahead information for use
- # with LALR parsing
- # -----------------------------------------------------------------------------
-
- def add_lalr_lookaheads(self,C):
- # Determine all of the nullable nonterminals
- nullable = self.compute_nullable_nonterminals()
-
- # Find all non-terminal transitions
- trans = self.find_nonterminal_transitions(C)
-
- # Compute read sets
- readsets = self.compute_read_sets(C,trans,nullable)
-
- # Compute lookback/includes relations
- lookd, included = self.compute_lookback_includes(C,trans,nullable)
-
- # Compute LALR FOLLOW sets
- followsets = self.compute_follow_sets(trans,readsets,included)
-
- # Add all of the lookaheads
- self.add_lookaheads(lookd,followsets)
-
- # -----------------------------------------------------------------------------
- # lr_parse_table()
- #
- # This function constructs the parse tables for SLR or LALR
- # -----------------------------------------------------------------------------
- def lr_parse_table(self):
- Productions = self.grammar.Productions
- Precedence = self.grammar.Precedence
- goto = self.lr_goto # Goto array
- action = self.lr_action # Action array
- log = self.log # Logger for output
-
- actionp = { } # Action production array (temporary)
-
- log.info("Parsing method: %s", self.lr_method)
-
- # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items
- # This determines the number of states
-
- C = self.lr0_items()
-
- if self.lr_method == 'LALR':
- self.add_lalr_lookaheads(C)
-
- # Build the parser table, state by state
- st = 0
- for I in C:
- # Loop over each production in I
- actlist = [ ] # List of actions
- st_action = { }
- st_actionp = { }
- st_goto = { }
- log.info("")
- log.info("state %d", st)
- log.info("")
- for p in I:
- log.info(" (%d) %s", p.number, str(p))
- log.info("")
-
- for p in I:
- if p.len == p.lr_index + 1:
- if p.name == "S'":
- # Start symbol. Accept!
- st_action["$end"] = 0
- st_actionp["$end"] = p
- else:
- # We are at the end of a production. Reduce!
- if self.lr_method == 'LALR':
- laheads = p.lookaheads[st]
- else:
- laheads = self.grammar.Follow[p.name]
- for a in laheads:
- actlist.append((a,p,"reduce using rule %d (%s)" % (p.number,p)))
- r = st_action.get(a,None)
- if r is not None:
- # Whoa. Have a shift/reduce or reduce/reduce conflict
- if r > 0:
- # Need to decide on shift or reduce here
- # By default we favor shifting. Need to add
- # some precedence rules here.
- sprec,slevel = Productions[st_actionp[a].number].prec
- rprec,rlevel = Precedence.get(a,('right',0))
- if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')):
- # We really need to reduce here.
- st_action[a] = -p.number
- st_actionp[a] = p
- if not slevel and not rlevel:
- log.info(" ! shift/reduce conflict for %s resolved as reduce",a)
- self.sr_conflicts.append((st,a,'reduce'))
- Productions[p.number].reduced += 1
- elif (slevel == rlevel) and (rprec == 'nonassoc'):
- st_action[a] = None
- else:
- # Hmmm. Guess we'll keep the shift
- if not rlevel:
- log.info(" ! shift/reduce conflict for %s resolved as shift",a)
- self.sr_conflicts.append((st,a,'shift'))
- elif r < 0:
- # Reduce/reduce conflict. In this case, we favor the rule
- # that was defined first in the grammar file
- oldp = Productions[-r]
- pp = Productions[p.number]
- if oldp.line > pp.line:
- st_action[a] = -p.number
- st_actionp[a] = p
- chosenp,rejectp = pp,oldp
- Productions[p.number].reduced += 1
- Productions[oldp.number].reduced -= 1
- else:
- chosenp,rejectp = oldp,pp
- self.rr_conflicts.append((st,chosenp,rejectp))
- log.info(" ! reduce/reduce conflict for %s resolved using rule %d (%s)", a,st_actionp[a].number, st_actionp[a])
- else:
- raise LALRError("Unknown conflict in state %d" % st)
- else:
- st_action[a] = -p.number
- st_actionp[a] = p
- Productions[p.number].reduced += 1
- else:
- i = p.lr_index
- a = p.prod[i+1] # Get symbol right after the "."
- if a in self.grammar.Terminals:
- g = self.lr0_goto(I,a)
- j = self.lr0_cidhash.get(id(g),-1)
- if j >= 0:
- # We are in a shift state
- actlist.append((a,p,"shift and go to state %d" % j))
- r = st_action.get(a,None)
- if r is not None:
- # Whoa have a shift/reduce or shift/shift conflict
- if r > 0:
- if r != j:
- raise LALRError("Shift/shift conflict in state %d" % st)
- elif r < 0:
- # Do a precedence check.
- # - if precedence of reduce rule is higher, we reduce.
- # - if precedence of reduce is same and left assoc, we reduce.
- # - otherwise we shift
- rprec,rlevel = Productions[st_actionp[a].number].prec
- sprec,slevel = Precedence.get(a,('right',0))
- if (slevel > rlevel) or ((slevel == rlevel) and (rprec == 'right')):
- # We decide to shift here... highest precedence to shift
- Productions[st_actionp[a].number].reduced -= 1
- st_action[a] = j
- st_actionp[a] = p
- if not rlevel:
- log.info(" ! shift/reduce conflict for %s resolved as shift",a)
- self.sr_conflicts.append((st,a,'shift'))
- elif (slevel == rlevel) and (rprec == 'nonassoc'):
- st_action[a] = None
- else:
- # Hmmm. Guess we'll keep the reduce
- if not slevel and not rlevel:
- log.info(" ! shift/reduce conflict for %s resolved as reduce",a)
- self.sr_conflicts.append((st,a,'reduce'))
-
- else:
- raise LALRError("Unknown conflict in state %d" % st)
- else:
- st_action[a] = j
- st_actionp[a] = p
-
- # Print the actions associated with each terminal
- _actprint = { }
- for a,p,m in actlist:
- if a in st_action:
- if p is st_actionp[a]:
- log.info(" %-15s %s",a,m)
- _actprint[(a,m)] = 1
- log.info("")
- # Print the actions that were not used. (debugging)
- not_used = 0
- for a,p,m in actlist:
- if a in st_action:
- if p is not st_actionp[a]:
- if not (a,m) in _actprint:
- log.debug(" ! %-15s [ %s ]",a,m)
- not_used = 1
- _actprint[(a,m)] = 1
- if not_used:
- log.debug("")
-
- # Construct the goto table for this state
-
- nkeys = { }
- for ii in I:
- for s in ii.usyms:
- if s in self.grammar.Nonterminals:
- nkeys[s] = None
- for n in nkeys:
- g = self.lr0_goto(I,n)
- j = self.lr0_cidhash.get(id(g),-1)
- if j >= 0:
- st_goto[n] = j
- log.info(" %-30s shift and go to state %d",n,j)
-
- action[st] = st_action
- actionp[st] = st_actionp
- goto[st] = st_goto
- st += 1
-
-
- # -----------------------------------------------------------------------------
- # write()
- #
- # This function writes the LR parsing tables to a file
- # -----------------------------------------------------------------------------
-
- def write_table(self,modulename,outputdir='',signature=""):
- basemodulename = modulename.split(".")[-1]
- filename = os.path.join(outputdir,basemodulename) + ".py"
- try:
- f = open(filename,"w")
-
- f.write("""
-# %s
-# This file is automatically generated. Do not edit.
-_tabversion = %r
-
-_lr_method = %r
-
-_lr_signature = %r
- """ % (filename, __tabversion__, self.lr_method, signature))
-
- # Change smaller to 0 to go back to original tables
- smaller = 1
-
- # Factor out names to try and make smaller
- if smaller:
- items = { }
-
- for s,nd in self.lr_action.items():
- for name,v in nd.items():
- i = items.get(name)
- if not i:
- i = ([],[])
- items[name] = i
- i[0].append(s)
- i[1].append(v)
-
- f.write("\n_lr_action_items = {")
- for k,v in items.items():
- f.write("%r:([" % k)
- for i in v[0]:
- f.write("%r," % i)
- f.write("],[")
- for i in v[1]:
- f.write("%r," % i)
-
- f.write("]),")
- f.write("}\n")
-
- f.write("""
-_lr_action = { }
-for _k, _v in _lr_action_items.items():
- for _x,_y in zip(_v[0],_v[1]):
- if not _x in _lr_action: _lr_action[_x] = { }
- _lr_action[_x][_k] = _y
-del _lr_action_items
-""")
-
- else:
- f.write("\n_lr_action = { ");
- for k,v in self.lr_action.items():
- f.write("(%r,%r):%r," % (k[0],k[1],v))
- f.write("}\n");
-
- if smaller:
- # Factor out names to try and make smaller
- items = { }
-
- for s,nd in self.lr_goto.items():
- for name,v in nd.items():
- i = items.get(name)
- if not i:
- i = ([],[])
- items[name] = i
- i[0].append(s)
- i[1].append(v)
-
- f.write("\n_lr_goto_items = {")
- for k,v in items.items():
- f.write("%r:([" % k)
- for i in v[0]:
- f.write("%r," % i)
- f.write("],[")
- for i in v[1]:
- f.write("%r," % i)
-
- f.write("]),")
- f.write("}\n")
-
- f.write("""
-_lr_goto = { }
-for _k, _v in _lr_goto_items.items():
- for _x,_y in zip(_v[0],_v[1]):
- if not _x in _lr_goto: _lr_goto[_x] = { }
- _lr_goto[_x][_k] = _y
-del _lr_goto_items
-""")
- else:
- f.write("\n_lr_goto = { ");
- for k,v in self.lr_goto.items():
- f.write("(%r,%r):%r," % (k[0],k[1],v))
- f.write("}\n");
-
- # Write production table
- f.write("_lr_productions = [\n")
- for p in self.lr_productions:
- if p.func:
- f.write(" (%r,%r,%d,%r,%r,%d),\n" % (p.str,p.name, p.len, p.func,p.file,p.line))
- else:
- f.write(" (%r,%r,%d,None,None,None),\n" % (str(p),p.name, p.len))
- f.write("]\n")
- f.close()
-
- except IOError:
- e = sys.exc_info()[1]
- sys.stderr.write("Unable to create '%s'\n" % filename)
- sys.stderr.write(str(e)+"\n")
- return
-
-
- # -----------------------------------------------------------------------------
- # pickle_table()
- #
- # This function pickles the LR parsing tables to a supplied file object
- # -----------------------------------------------------------------------------
-
- def pickle_table(self,filename,signature=""):
- try:
- import cPickle as pickle
- except ImportError:
- import pickle
- outf = open(filename,"wb")
- pickle.dump(__tabversion__,outf,pickle_protocol)
- pickle.dump(self.lr_method,outf,pickle_protocol)
- pickle.dump(signature,outf,pickle_protocol)
- pickle.dump(self.lr_action,outf,pickle_protocol)
- pickle.dump(self.lr_goto,outf,pickle_protocol)
-
- outp = []
- for p in self.lr_productions:
- if p.func:
- outp.append((p.str,p.name, p.len, p.func,p.file,p.line))
- else:
- outp.append((str(p),p.name,p.len,None,None,None))
- pickle.dump(outp,outf,pickle_protocol)
- outf.close()
-
-# -----------------------------------------------------------------------------
-# === INTROSPECTION ===
-#
-# The following functions and classes are used to implement the PLY
-# introspection features followed by the yacc() function itself.
-# -----------------------------------------------------------------------------
-
-# -----------------------------------------------------------------------------
-# get_caller_module_dict()
-#
-# This function returns a dictionary containing all of the symbols defined within
-# a caller further down the call stack. This is used to get the environment
-# associated with the yacc() call if none was provided.
-# -----------------------------------------------------------------------------
-
-def get_caller_module_dict(levels):
- try:
- raise RuntimeError
- except RuntimeError:
- e,b,t = sys.exc_info()
- f = t.tb_frame
- while levels > 0:
- f = f.f_back
- levels -= 1
- ldict = f.f_globals.copy()
- if f.f_globals != f.f_locals:
- ldict.update(f.f_locals)
-
- return ldict
-
-# -----------------------------------------------------------------------------
-# parse_grammar()
-#
-# This takes a raw grammar rule string and parses it into production data
-# -----------------------------------------------------------------------------
-def parse_grammar(doc,file,line):
- grammar = []
- # Split the doc string into lines
- pstrings = doc.splitlines()
- lastp = None
- dline = line
- for ps in pstrings:
- dline += 1
- p = ps.split()
- if not p: continue
- try:
- if p[0] == '|':
- # This is a continuation of a previous rule
- if not lastp:
- raise SyntaxError("%s:%d: Misplaced '|'" % (file,dline))
- prodname = lastp
- syms = p[1:]
- else:
- prodname = p[0]
- lastp = prodname
- syms = p[2:]
- assign = p[1]
- if assign != ':' and assign != '::=':
- raise SyntaxError("%s:%d: Syntax error. Expected ':'" % (file,dline))
-
- grammar.append((file,dline,prodname,syms))
- except SyntaxError:
- raise
- except Exception:
- raise SyntaxError("%s:%d: Syntax error in rule '%s'" % (file,dline,ps.strip()))
-
- return grammar
-
-# -----------------------------------------------------------------------------
-# ParserReflect()
-#
-# This class represents information extracted for building a parser including
-# start symbol, error function, tokens, precedence list, action functions,
-# etc.
-# -----------------------------------------------------------------------------
-class ParserReflect(object):
- def __init__(self,pdict,log=None):
- self.pdict = pdict
- self.start = None
- self.error_func = None
- self.tokens = None
- self.files = {}
- self.grammar = []
- self.error = 0
-
- if log is None:
- self.log = PlyLogger(sys.stderr)
- else:
- self.log = log
-
- # Get all of the basic information
- def get_all(self):
- self.get_start()
- self.get_error_func()
- self.get_tokens()
- self.get_precedence()
- self.get_pfunctions()
-
- # Validate all of the information
- def validate_all(self):
- self.validate_start()
- self.validate_error_func()
- self.validate_tokens()
- self.validate_precedence()
- self.validate_pfunctions()
- self.validate_files()
- return self.error
-
- # Compute a signature over the grammar
- def signature(self):
- try:
- from hashlib import md5
- except ImportError:
- from md5 import md5
- try:
- sig = md5()
- if self.start:
- sig.update(self.start.encode('latin-1'))
- if self.prec:
- sig.update("".join(["".join(p) for p in self.prec]).encode('latin-1'))
- if self.tokens:
- sig.update(" ".join(self.tokens).encode('latin-1'))
- for f in self.pfuncs:
- if f[3]:
- sig.update(f[3].encode('latin-1'))
- except (TypeError,ValueError):
- pass
- return sig.digest()
-
- # -----------------------------------------------------------------------------
- # validate_file()
- #
- # This method checks to see if there are duplicated p_rulename() functions
- # in the parser module file. Without this function, it is really easy for
- # users to make mistakes by cutting and pasting code fragments (and it's a real
- # bugger to try and figure out why the resulting parser doesn't work). Therefore,
- # we just do a little regular expression pattern matching of def statements
- # to try and detect duplicates.
- # -----------------------------------------------------------------------------
-
- def validate_files(self):
- # Match def p_funcname(
- fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(')
-
- for filename in self.files.keys():
- base,ext = os.path.splitext(filename)
- if ext != '.py': return 1 # No idea. Assume it's okay.
-
- try:
- f = open(filename)
- lines = f.readlines()
- f.close()
- except IOError:
- continue
-
- counthash = { }
- for linen,l in enumerate(lines):
- linen += 1
- m = fre.match(l)
- if m:
- name = m.group(1)
- prev = counthash.get(name)
- if not prev:
- counthash[name] = linen
- else:
- self.log.warning("%s:%d: Function %s redefined. Previously defined on line %d", filename,linen,name,prev)
-
- # Get the start symbol
- def get_start(self):
- self.start = self.pdict.get('start')
-
- # Validate the start symbol
- def validate_start(self):
- if self.start is not None:
- if not isinstance(self.start,str):
- self.log.error("'start' must be a string")
-
- # Look for error handler
- def get_error_func(self):
- self.error_func = self.pdict.get('p_error')
-
- # Validate the error function
- def validate_error_func(self):
- if self.error_func:
- if isinstance(self.error_func,types.FunctionType):
- ismethod = 0
- elif isinstance(self.error_func, types.MethodType):
- ismethod = 1
- else:
- self.log.error("'p_error' defined, but is not a function or method")
- self.error = 1
- return
-
- eline = func_code(self.error_func).co_firstlineno
- efile = func_code(self.error_func).co_filename
- self.files[efile] = 1
-
- if (func_code(self.error_func).co_argcount != 1+ismethod):
- self.log.error("%s:%d: p_error() requires 1 argument",efile,eline)
- self.error = 1
-
- # Get the tokens map
- def get_tokens(self):
- tokens = self.pdict.get("tokens",None)
- if not tokens:
- self.log.error("No token list is defined")
- self.error = 1
- return
-
- if not isinstance(tokens,(list, tuple)):
- self.log.error("tokens must be a list or tuple")
- self.error = 1
- return
-
- if not tokens:
- self.log.error("tokens is empty")
- self.error = 1
- return
-
- self.tokens = tokens
-
- # Validate the tokens
- def validate_tokens(self):
- # Validate the tokens.
- if 'error' in self.tokens:
- self.log.error("Illegal token name 'error'. Is a reserved word")
- self.error = 1
- return
-
- terminals = {}
- for n in self.tokens:
- if n in terminals:
- self.log.warning("Token '%s' multiply defined", n)
- terminals[n] = 1
-
- # Get the precedence map (if any)
- def get_precedence(self):
- self.prec = self.pdict.get("precedence",None)
-
- # Validate and parse the precedence map
- def validate_precedence(self):
- preclist = []
- if self.prec:
- if not isinstance(self.prec,(list,tuple)):
- self.log.error("precedence must be a list or tuple")
- self.error = 1
- return
- for level,p in enumerate(self.prec):
- if not isinstance(p,(list,tuple)):
- self.log.error("Bad precedence table")
- self.error = 1
- return
-
- if len(p) < 2:
- self.log.error("Malformed precedence entry %s. Must be (assoc, term, ..., term)",p)
- self.error = 1
- return
- assoc = p[0]
- if not isinstance(assoc,str):
- self.log.error("precedence associativity must be a string")
- self.error = 1
- return
- for term in p[1:]:
- if not isinstance(term,str):
- self.log.error("precedence items must be strings")
- self.error = 1
- return
- preclist.append((term,assoc,level+1))
- self.preclist = preclist
-
- # Get all p_functions from the grammar
- def get_pfunctions(self):
- p_functions = []
- for name, item in self.pdict.items():
- if name[:2] != 'p_': continue
- if name == 'p_error': continue
- if isinstance(item,(types.FunctionType,types.MethodType)):
- line = func_code(item).co_firstlineno
- file = func_code(item).co_filename
- p_functions.append((line,file,name,item.__doc__))
-
- # Sort all of the actions by line number
- p_functions.sort()
- self.pfuncs = p_functions
-
-
- # Validate all of the p_functions
- def validate_pfunctions(self):
- grammar = []
- # Check for non-empty symbols
- if len(self.pfuncs) == 0:
- self.log.error("no rules of the form p_rulename are defined")
- self.error = 1
- return
-
- for line, file, name, doc in self.pfuncs:
- func = self.pdict[name]
- if isinstance(func, types.MethodType):
- reqargs = 2
- else:
- reqargs = 1
- if func_code(func).co_argcount > reqargs:
- self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,func.__name__)
- self.error = 1
- elif func_code(func).co_argcount < reqargs:
- self.log.error("%s:%d: Rule '%s' requires an argument",file,line,func.__name__)
- self.error = 1
- elif not func.__doc__:
- self.log.warning("%s:%d: No documentation string specified in function '%s' (ignored)",file,line,func.__name__)
- else:
- try:
- parsed_g = parse_grammar(doc,file,line)
- for g in parsed_g:
- grammar.append((name, g))
- except SyntaxError:
- e = sys.exc_info()[1]
- self.log.error(str(e))
- self.error = 1
-
- # Looks like a valid grammar rule
- # Mark the file in which defined.
- self.files[file] = 1
-
- # Secondary validation step that looks for p_ definitions that are not functions
- # or functions that look like they might be grammar rules.
-
- for n,v in self.pdict.items():
- if n[0:2] == 'p_' and isinstance(v, (types.FunctionType, types.MethodType)): continue
- if n[0:2] == 't_': continue
- if n[0:2] == 'p_' and n != 'p_error':
- self.log.warning("'%s' not defined as a function", n)
- if ((isinstance(v,types.FunctionType) and func_code(v).co_argcount == 1) or
- (isinstance(v,types.MethodType) and func_code(v).co_argcount == 2)):
- try:
- doc = v.__doc__.split(" ")
- if doc[1] == ':':
- self.log.warning("%s:%d: Possible grammar rule '%s' defined without p_ prefix",
- func_code(v).co_filename, func_code(v).co_firstlineno,n)
- except Exception:
- pass
-
- self.grammar = grammar
-
-# -----------------------------------------------------------------------------
-# yacc(module)
-#
-# Build a parser
-# -----------------------------------------------------------------------------
-
-def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None,
- check_recursion=1, optimize=0, write_tables=1, debugfile=debug_file,outputdir='',
- debuglog=None, errorlog = None, picklefile=None):
-
- global parse # Reference to the parsing method of the last built parser
-
- # If pickling is enabled, table files are not created
-
- if picklefile:
- write_tables = 0
-
- if errorlog is None:
- errorlog = PlyLogger(sys.stderr)
-
- # Get the module dictionary used for the parser
- if module:
- _items = [(k,getattr(module,k)) for k in dir(module)]
- pdict = dict(_items)
- else:
- pdict = get_caller_module_dict(2)
-
- # Collect parser information from the dictionary
- pinfo = ParserReflect(pdict,log=errorlog)
- pinfo.get_all()
-
- if pinfo.error:
- raise YaccError("Unable to build parser")
-
- # Check signature against table files (if any)
- signature = pinfo.signature()
-
- # Read the tables
- try:
- lr = LRTable()
- if picklefile:
- read_signature = lr.read_pickle(picklefile)
- else:
- read_signature = lr.read_table(tabmodule)
- if optimize or (read_signature == signature):
- try:
- lr.bind_callables(pinfo.pdict)
- parser = LRParser(lr,pinfo.error_func)
- parse = parser.parse
- return parser
- except Exception:
- e = sys.exc_info()[1]
- errorlog.warning("There was a problem loading the table file: %s", repr(e))
- except VersionError:
- e = sys.exc_info()
- errorlog.warning(str(e))
- except Exception:
- pass
-
- if debuglog is None:
- if debug:
- debuglog = PlyLogger(open(debugfile,"w"))
- else:
- debuglog = NullLogger()
-
- debuglog.info("Created by PLY version %s (http://www.dabeaz.com/ply)", __version__)
-
-
- errors = 0
-
- # Validate the parser information
- if pinfo.validate_all():
- raise YaccError("Unable to build parser")
-
- if not pinfo.error_func:
- errorlog.warning("no p_error() function is defined")
-
- # Create a grammar object
- grammar = Grammar(pinfo.tokens)
-
- # Set precedence level for terminals
- for term, assoc, level in pinfo.preclist:
- try:
- grammar.set_precedence(term,assoc,level)
- except GrammarError:
- e = sys.exc_info()[1]
- errorlog.warning("%s",str(e))
-
- # Add productions to the grammar
- for funcname, gram in pinfo.grammar:
- file, line, prodname, syms = gram
- try:
- grammar.add_production(prodname,syms,funcname,file,line)
- except GrammarError:
- e = sys.exc_info()[1]
- errorlog.error("%s",str(e))
- errors = 1
-
- # Set the grammar start symbols
- try:
- if start is None:
- grammar.set_start(pinfo.start)
- else:
- grammar.set_start(start)
- except GrammarError:
- e = sys.exc_info()[1]
- errorlog.error(str(e))
- errors = 1
-
- if errors:
- raise YaccError("Unable to build parser")
-
- # Verify the grammar structure
- undefined_symbols = grammar.undefined_symbols()
- for sym, prod in undefined_symbols:
- errorlog.error("%s:%d: Symbol '%s' used, but not defined as a token or a rule",prod.file,prod.line,sym)
- errors = 1
-
- unused_terminals = grammar.unused_terminals()
- if unused_terminals:
- debuglog.info("")
- debuglog.info("Unused terminals:")
- debuglog.info("")
- for term in unused_terminals:
- errorlog.warning("Token '%s' defined, but not used", term)
- debuglog.info(" %s", term)
-
- # Print out all productions to the debug log
- if debug:
- debuglog.info("")
- debuglog.info("Grammar")
- debuglog.info("")
- for n,p in enumerate(grammar.Productions):
- debuglog.info("Rule %-5d %s", n, p)
-
- # Find unused non-terminals
- unused_rules = grammar.unused_rules()
- for prod in unused_rules:
- errorlog.warning("%s:%d: Rule '%s' defined, but not used", prod.file, prod.line, prod.name)
-
- if len(unused_terminals) == 1:
- errorlog.warning("There is 1 unused token")
- if len(unused_terminals) > 1:
- errorlog.warning("There are %d unused tokens", len(unused_terminals))
-
- if len(unused_rules) == 1:
- errorlog.warning("There is 1 unused rule")
- if len(unused_rules) > 1:
- errorlog.warning("There are %d unused rules", len(unused_rules))
-
- if debug:
- debuglog.info("")
- debuglog.info("Terminals, with rules where they appear")
- debuglog.info("")
- terms = list(grammar.Terminals)
- terms.sort()
- for term in terms:
- debuglog.info("%-20s : %s", term, " ".join([str(s) for s in grammar.Terminals[term]]))
-
- debuglog.info("")
- debuglog.info("Nonterminals, with rules where they appear")
- debuglog.info("")
- nonterms = list(grammar.Nonterminals)
- nonterms.sort()
- for nonterm in nonterms:
- debuglog.info("%-20s : %s", nonterm, " ".join([str(s) for s in grammar.Nonterminals[nonterm]]))
- debuglog.info("")
-
- if check_recursion:
- unreachable = grammar.find_unreachable()
- for u in unreachable:
- errorlog.warning("Symbol '%s' is unreachable",u)
-
- infinite = grammar.infinite_cycles()
- for inf in infinite:
- errorlog.error("Infinite recursion detected for symbol '%s'", inf)
- errors = 1
-
- unused_prec = grammar.unused_precedence()
- for term, assoc in unused_prec:
- errorlog.error("Precedence rule '%s' defined for unknown symbol '%s'", assoc, term)
- errors = 1
-
- if errors:
- raise YaccError("Unable to build parser")
-
- # Run the LRGeneratedTable on the grammar
- if debug:
- errorlog.debug("Generating %s tables", method)
-
- lr = LRGeneratedTable(grammar,method,debuglog)
-
- if debug:
- num_sr = len(lr.sr_conflicts)
-
- # Report shift/reduce and reduce/reduce conflicts
- if num_sr == 1:
- errorlog.warning("1 shift/reduce conflict")
- elif num_sr > 1:
- errorlog.warning("%d shift/reduce conflicts", num_sr)
-
- num_rr = len(lr.rr_conflicts)
- if num_rr == 1:
- errorlog.warning("1 reduce/reduce conflict")
- elif num_rr > 1:
- errorlog.warning("%d reduce/reduce conflicts", num_rr)
-
- # Write out conflicts to the output file
- if debug and (lr.sr_conflicts or lr.rr_conflicts):
- debuglog.warning("")
- debuglog.warning("Conflicts:")
- debuglog.warning("")
-
- for state, tok, resolution in lr.sr_conflicts:
- debuglog.warning("shift/reduce conflict for %s in state %d resolved as %s", tok, state, resolution)
-
- already_reported = {}
- for state, rule, rejected in lr.rr_conflicts:
- if (state,id(rule),id(rejected)) in already_reported:
- continue
- debuglog.warning("reduce/reduce conflict in state %d resolved using rule (%s)", state, rule)
- debuglog.warning("rejected rule (%s) in state %d", rejected,state)
- errorlog.warning("reduce/reduce conflict in state %d resolved using rule (%s)", state, rule)
- errorlog.warning("rejected rule (%s) in state %d", rejected, state)
- already_reported[state,id(rule),id(rejected)] = 1
-
- warned_never = []
- for state, rule, rejected in lr.rr_conflicts:
- if not rejected.reduced and (rejected not in warned_never):
- debuglog.warning("Rule (%s) is never reduced", rejected)
- errorlog.warning("Rule (%s) is never reduced", rejected)
- warned_never.append(rejected)
-
- # Write the table file if requested
- if write_tables:
- lr.write_table(tabmodule,outputdir,signature)
-
- # Write a pickled version of the tables
- if picklefile:
- lr.pickle_table(picklefile,signature)
-
- # Build the parser
- lr.bind_callables(pinfo.pdict)
- parser = LRParser(lr,pinfo.error_func)
-
- parse = parser.parse
- return parser
diff --git a/src/components/script/dom/bindings/codegen/pythonpath.py b/src/components/script/dom/bindings/codegen/pythonpath.py
deleted file mode 100644
index 49b2d2f740f..00000000000
--- a/src/components/script/dom/bindings/codegen/pythonpath.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# 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/.
-
-"""
-Run a python script, adding extra directories to the python path.
-"""
-
-
-def main(args):
- def usage():
- print >>sys.stderr, "pythonpath.py -I directory script.py [args...]"
- sys.exit(150)
-
- paths = []
-
- while True:
- try:
- arg = args[0]
- except IndexError:
- usage()
-
- if arg == '-I':
- args.pop(0)
- try:
- path = args.pop(0)
- except IndexError:
- usage()
-
- paths.append(os.path.abspath(path))
- continue
-
- if arg.startswith('-I'):
- paths.append(os.path.abspath(args.pop(0)[2:]))
- continue
-
- if arg.startswith('-D'):
- os.chdir(args.pop(0)[2:])
- continue
-
- break
-
- script = args[0]
-
- sys.path[0:0] = [os.path.abspath(os.path.dirname(script))] + paths
- sys.argv = args
- sys.argc = len(args)
-
- frozenglobals['__name__'] = '__main__'
- frozenglobals['__file__'] = script
-
- execfile(script, frozenglobals)
-
-# Freeze scope here ... why this makes things work I have no idea ...
-frozenglobals = globals()
-
-import sys, os
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.cpp b/src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.cpp
deleted file mode 100644
index dfa17d23400..00000000000
--- a/src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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/. */
-
-#include "Skeleton.h"
-#include "mozilla/dom/SkeletonBinding.h"
-#include "nsContentUtils.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(Skeleton)
-NS_IMPL_CYCLE_COLLECTING_ADDREF(Skeleton)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(Skeleton)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Skeleton)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-Skeleton::Skeleton()
-{
- SetIsDOMBinding();
-}
-
-Skeleton::~Skeleton()
-{
-}
-
-JSObject*
-Skeleton::WrapObject(JSContext* aCx, JSObject* aScope,
- bool* aTriedToWrap)
-{
- return SkeletonBinding::Wrap(aCx, aScope, this, aTriedToWrap);
-}
-
-}
-}
-
diff --git a/src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.h b/src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.h
deleted file mode 100644
index 286cff9af4a..00000000000
--- a/src/components/script/dom/bindings/codegen/stubgenerator/Skeleton.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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/. */
-
-#pragma once
-
-#include "nsWrapperCache.h"
-#include "nsCycleCollectionParticipant.h"
-#include "mozilla/Attributes.h"
-
-struct JSContext;
-
-namespace mozilla {
-namespace dom {
-
-class Skeleton MOZ_FINAL : public nsISupports,
- public nsWrapperCache
-{
-public:
- Skeleton();
- ~Skeleton();
-
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Skeleton)
-
- void* GetParentObject() const
- {
- // TODO: return something sensible here, and change the return type
- return somethingSensible;
- }
-
- virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
- bool* aTriedToWrap);
-};
-
-}
-}
-
diff --git a/src/components/script/dom/bindings/codegen/stubgenerator/generate.sh b/src/components/script/dom/bindings/codegen/stubgenerator/generate.sh
deleted file mode 100644
index 52577f6f42f..00000000000
--- a/src/components/script/dom/bindings/codegen/stubgenerator/generate.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-# This script creates a skeleton implementation for a C++ class which
-# implements a Web IDL interface.
-
-# This script is released into the public domain.
-
-if [ -z "$1" ]; then
- echo usage: ./generate.sh ClassName
- exit 1
-fi
-
-expression="s/Skeleton/$1/g"
-
-sed "$expression" < Skeleton.h > "$1.h"
-sed "$expression" < Skeleton.cpp > "$1.cpp"
-
diff --git a/src/components/script/dom/bindings/codegen/test/Makefile.in b/src/components/script/dom/bindings/codegen/test/Makefile.in
deleted file mode 100644
index d8104db5ffd..00000000000
--- a/src/components/script/dom/bindings/codegen/test/Makefile.in
+++ /dev/null
@@ -1,87 +0,0 @@
-# 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/.
-
-DEPTH = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-relativesrcdir = @relativesrcdir@
-
-MODULE = dom
-LIBRARY_NAME = dombindings_test_s
-LIBXUL_LIBRARY = 1
-FORCE_STATIC_LIB = 1
-# Do NOT export this library. We don't actually want our test code
-# being added to libxul or anything.
-
-include $(DEPTH)/config/autoconf.mk
-
-# Need this to find all our DOM source files.
-include $(topsrcdir)/dom/dom-config.mk
-
-# And need this for $(test_webidl_files)
-include $(topsrcdir)/dom/webidl/WebIDL.mk
-
-# But the webidl actually lives in our parent dir
-test_webidl_files := $(addprefix ../,$(test_webidl_files))
-
-CPPSRCS := $(subst .webidl,Binding.cpp,$(test_webidl_files))
-
-LOCAL_INCLUDES += \
- -I$(topsrcdir)/js/xpconnect/src \
- -I$(topsrcdir)/js/xpconnect/wrappers \
- -I$(topsrcdir)/dom/bindings \
- $(NULL)
-
-
-# If you change bindinggen_dependencies here, change it in
-# dom/bindings/Makefile.in too. But note that we include ../Makefile
-# here manually, since $(GLOBAL_DEPS) won't cover it.
-bindinggen_dependencies := \
- ../BindingGen.py \
- ../Bindings.conf \
- ../Configuration.py \
- ../Codegen.py \
- ../parser/WebIDL.py \
- ../ParserResults.pkl \
- ../Makefile \
- $(GLOBAL_DEPS) \
- $(NULL)
-
-MOCHITEST_FILES := \
- test_bug773326.html \
- test_enums.html \
- test_integers.html \
- test_interfaceToString.html \
- test_lookupGetter.html \
- test_InstanceOf.html \
- test_traceProtos.html \
- test_forOf.html \
- forOf_iframe.html \
- test_sequence_wrapping.html \
- file_bug775543.html \
- test_bug788369.html \
- $(NULL)
-
-MOCHITEST_CHROME_FILES = \
- test_bug775543.html \
- $(NULL)
-
-# Include rules.mk before any of our targets so our first target is coming from
-# rules.mk and running make with no target in this dir does the right thing.
-include $(topsrcdir)/config/rules.mk
-
-$(CPPSRCS): ../%Binding.cpp: $(bindinggen_dependencies) \
- ../%.webidl \
- $(NULL)
- $(MAKE) -C .. $*Binding.h
- $(MAKE) -C .. $*Binding.cpp
-
-check::
- $(PYTHON) $(topsrcdir)/config/pythonpath.py \
- $(PLY_INCLUDE) $(srcdir)/../parser/runtests.py
-
-check-interactive:
- $(PYTHON) $(topsrcdir)/config/pythonpath.py \
- $(PLY_INCLUDE) $(srcdir)/../parser/runtests.py -q
diff --git a/src/components/script/dom/bindings/codegen/test/TestBindingHeader.h b/src/components/script/dom/bindings/codegen/test/TestBindingHeader.h
deleted file mode 100644
index 1fbab0a9fb8..00000000000
--- a/src/components/script/dom/bindings/codegen/test/TestBindingHeader.h
+++ /dev/null
@@ -1,653 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-#ifndef TestBindingHeader_h
-#define TestBindingHeader_h
-
-#include "nsWrapperCache.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/TypedArray.h"
-#include "nsCOMPtr.h"
-// We don't export TestCodeGenBinding.h, but it's right in our parent dir.
-#include "../TestCodeGenBinding.h"
-#include "mozilla/dom/UnionTypes.h"
-
-namespace mozilla {
-namespace dom {
-
-// IID for the TestNonCastableInterface
-#define NS_TEST_NONCASTABLE_INTERFACE_IID \
-{ 0x7c9f8ee2, 0xc9bf, 0x46ca, \
- { 0xa0, 0xa9, 0x03, 0xa8, 0xd6, 0x30, 0x0e, 0xde } }
-
-class TestNonCastableInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_NONCASTABLE_INTERFACE_IID)
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-};
-
-// IID for the IndirectlyImplementedInterface
-#define NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID \
-{ 0xfed55b69, 0x7012, 0x4849, \
- { 0xaf, 0x56, 0x4b, 0xa9, 0xee, 0x41, 0x30, 0x89 } }
-
-class IndirectlyImplementedInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECLARE_STATIC_IID_ACCESSOR(NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID)
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-
- bool IndirectlyImplementedProperty();
- void IndirectlyImplementedProperty(bool);
- void IndirectlyImplementedMethod();
-};
-
-// IID for the TestExternalInterface
-#define NS_TEST_EXTERNAL_INTERFACE_IID \
-{ 0xd5ba0c99, 0x9b1d, 0x4e71, \
- { 0x8a, 0x94, 0x56, 0x38, 0x6c, 0xa3, 0xda, 0x3d } }
-class TestExternalInterface : public nsISupports
-{
-public:
- NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_EXTERNAL_INTERFACE_IID)
- NS_DECL_ISUPPORTS
-};
-
-// IID for the TestCallbackInterface
-#define NS_TEST_CALLBACK_INTERFACE_IID \
-{ 0xbf711ba4, 0xc8f6, 0x46cf, \
- { 0xba, 0x5b, 0xaa, 0xe2, 0x78, 0x18, 0xe6, 0x4a } }
-class TestCallbackInterface : public nsISupports
-{
-public:
- NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_CALLBACK_INTERFACE_IID)
- NS_DECL_ISUPPORTS
-};
-
-class TestNonWrapperCacheInterface : public nsISupports
-{
-public:
- NS_DECL_ISUPPORTS
-
- virtual JSObject* WrapObject(JSContext* cx, JSObject* scope);
-};
-
-class OnlyForUseInConstructor : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_ISUPPORTS
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-};
-
-class TestInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-
- // And now our actual WebIDL API
- // Constructors
- static
- already_AddRefed<TestInterface> Constructor(nsISupports*, ErrorResult&);
- static
- already_AddRefed<TestInterface> Constructor(nsISupports*, const nsAString&,
- ErrorResult&);
- static
- already_AddRefed<TestInterface> Constructor(nsISupports*, uint32_t,
- Nullable<bool>&, ErrorResult&);
- static
- already_AddRefed<TestInterface> Constructor(nsISupports*, TestInterface*,
- ErrorResult&);
- static
- already_AddRefed<TestInterface> Constructor(nsISupports*,
- TestNonCastableInterface&,
- ErrorResult&);
- /* static
- already_AddRefed<TestInterface> Constructor(nsISupports*,
- uint32_t, uint32_t,
- const TestInterfaceOrOnlyForUseInConstructor&,
- ErrorResult&);
- */
-
- // Integer types
- int8_t ReadonlyByte();
- int8_t WritableByte();
- void SetWritableByte(int8_t);
- void PassByte(int8_t);
- int8_t ReceiveByte();
- void PassOptionalByte(const Optional<int8_t>&);
- void PassOptionalByteWithDefault(int8_t);
- void PassNullableByte(Nullable<int8_t>&);
- void PassOptionalNullableByte(const Optional< Nullable<int8_t> >&);
-
- int16_t ReadonlyShort();
- int16_t WritableShort();
- void SetWritableShort(int16_t);
- void PassShort(int16_t);
- int16_t ReceiveShort();
- void PassOptionalShort(const Optional<int16_t>&);
- void PassOptionalShortWithDefault(int16_t);
-
- int32_t ReadonlyLong();
- int32_t WritableLong();
- void SetWritableLong(int32_t);
- void PassLong(int32_t);
- int16_t ReceiveLong();
- void PassOptionalLong(const Optional<int32_t>&);
- void PassOptionalLongWithDefault(int32_t);
-
- int64_t ReadonlyLongLong();
- int64_t WritableLongLong();
- void SetWritableLongLong(int64_t);
- void PassLongLong(int64_t);
- int64_t ReceiveLongLong();
- void PassOptionalLongLong(const Optional<int64_t>&);
- void PassOptionalLongLongWithDefault(int64_t);
-
- uint8_t ReadonlyOctet();
- uint8_t WritableOctet();
- void SetWritableOctet(uint8_t);
- void PassOctet(uint8_t);
- uint8_t ReceiveOctet();
- void PassOptionalOctet(const Optional<uint8_t>&);
- void PassOptionalOctetWithDefault(uint8_t);
-
- uint16_t ReadonlyUnsignedShort();
- uint16_t WritableUnsignedShort();
- void SetWritableUnsignedShort(uint16_t);
- void PassUnsignedShort(uint16_t);
- uint16_t ReceiveUnsignedShort();
- void PassOptionalUnsignedShort(const Optional<uint16_t>&);
- void PassOptionalUnsignedShortWithDefault(uint16_t);
-
- uint32_t ReadonlyUnsignedLong();
- uint32_t WritableUnsignedLong();
- void SetWritableUnsignedLong(uint32_t);
- void PassUnsignedLong(uint32_t);
- uint32_t ReceiveUnsignedLong();
- void PassOptionalUnsignedLong(const Optional<uint32_t>&);
- void PassOptionalUnsignedLongWithDefault(uint32_t);
-
- uint64_t ReadonlyUnsignedLongLong();
- uint64_t WritableUnsignedLongLong();
- void SetWritableUnsignedLongLong(uint64_t);
- void PassUnsignedLongLong(uint64_t);
- uint64_t ReceiveUnsignedLongLong();
- void PassOptionalUnsignedLongLong(const Optional<uint64_t>&);
- void PassOptionalUnsignedLongLongWithDefault(uint64_t);
-
- // Interface types
- already_AddRefed<TestInterface> ReceiveSelf();
- already_AddRefed<TestInterface> ReceiveNullableSelf();
- TestInterface* ReceiveWeakSelf();
- TestInterface* ReceiveWeakNullableSelf();
- void PassSelf(TestInterface&);
- void PassSelf2(NonNull<TestInterface>&);
- void PassNullableSelf(TestInterface*);
- already_AddRefed<TestInterface> NonNullSelf();
- void SetNonNullSelf(TestInterface&);
- already_AddRefed<TestInterface> GetNullableSelf();
- void SetNullableSelf(TestInterface*);
- void PassOptionalSelf(const Optional<TestInterface*> &);
- void PassOptionalNonNullSelf(const Optional<NonNull<TestInterface> >&);
- void PassOptionalSelfWithDefault(TestInterface*);
-
- already_AddRefed<TestNonWrapperCacheInterface> ReceiveNonWrapperCacheInterface();
- already_AddRefed<TestNonWrapperCacheInterface> ReceiveNullableNonWrapperCacheInterface();
- void ReceiveNonWrapperCacheInterfaceSequence(nsTArray<nsRefPtr<TestNonWrapperCacheInterface> >&);
- void ReceiveNullableNonWrapperCacheInterfaceSequence(nsTArray<nsRefPtr<TestNonWrapperCacheInterface> >&);
- void ReceiveNonWrapperCacheInterfaceNullableSequence(Nullable<nsTArray<nsRefPtr<TestNonWrapperCacheInterface> > >&);
- void ReceiveNullableNonWrapperCacheInterfaceNullableSequence(Nullable<nsTArray<nsRefPtr<TestNonWrapperCacheInterface> > >&);
-
- already_AddRefed<TestNonCastableInterface> ReceiveOther();
- already_AddRefed<TestNonCastableInterface> ReceiveNullableOther();
- TestNonCastableInterface* ReceiveWeakOther();
- TestNonCastableInterface* ReceiveWeakNullableOther();
- void PassOther(TestNonCastableInterface&);
- void PassOther2(NonNull<TestNonCastableInterface>&);
- void PassNullableOther(TestNonCastableInterface*);
- already_AddRefed<TestNonCastableInterface> NonNullOther();
- void SetNonNullOther(TestNonCastableInterface&);
- already_AddRefed<TestNonCastableInterface> GetNullableOther();
- void SetNullableOther(TestNonCastableInterface*);
- void PassOptionalOther(const Optional<TestNonCastableInterface*>&);
- void PassOptionalNonNullOther(const Optional<NonNull<TestNonCastableInterface> >&);
- void PassOptionalOtherWithDefault(TestNonCastableInterface*);
-
- already_AddRefed<TestExternalInterface> ReceiveExternal();
- already_AddRefed<TestExternalInterface> ReceiveNullableExternal();
- TestExternalInterface* ReceiveWeakExternal();
- TestExternalInterface* ReceiveWeakNullableExternal();
- void PassExternal(TestExternalInterface*);
- void PassExternal2(TestExternalInterface*);
- void PassNullableExternal(TestExternalInterface*);
- already_AddRefed<TestExternalInterface> NonNullExternal();
- void SetNonNullExternal(TestExternalInterface*);
- already_AddRefed<TestExternalInterface> GetNullableExternal();
- void SetNullableExternal(TestExternalInterface*);
- void PassOptionalExternal(const Optional<TestExternalInterface*>&);
- void PassOptionalNonNullExternal(const Optional<TestExternalInterface*>&);
- void PassOptionalExternalWithDefault(TestExternalInterface*);
-
- already_AddRefed<TestCallbackInterface> ReceiveCallbackInterface();
- already_AddRefed<TestCallbackInterface> ReceiveNullableCallbackInterface();
- TestCallbackInterface* ReceiveWeakCallbackInterface();
- TestCallbackInterface* ReceiveWeakNullableCallbackInterface();
- void PassCallbackInterface(TestCallbackInterface&);
- void PassCallbackInterface2(OwningNonNull<TestCallbackInterface>);
- void PassNullableCallbackInterface(TestCallbackInterface*);
- already_AddRefed<TestCallbackInterface> NonNullCallbackInterface();
- void SetNonNullCallbackInterface(TestCallbackInterface&);
- already_AddRefed<TestCallbackInterface> GetNullableCallbackInterface();
- void SetNullableCallbackInterface(TestCallbackInterface*);
- void PassOptionalCallbackInterface(const Optional<nsRefPtr<TestCallbackInterface> >&);
- void PassOptionalNonNullCallbackInterface(const Optional<OwningNonNull<TestCallbackInterface> >&);
- void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterface*);
-
- already_AddRefed<IndirectlyImplementedInterface> ReceiveConsequentialInterface();
- void PassConsequentialInterface(IndirectlyImplementedInterface&);
-
- // Sequence types
- void ReceiveSequence(nsTArray<int32_t>&);
- void ReceiveNullableSequence(Nullable< nsTArray<int32_t> >&);
- void ReceiveSequenceOfNullableInts(nsTArray< Nullable<int32_t> >&);
- void ReceiveNullableSequenceOfNullableInts(Nullable< nsTArray< Nullable<int32_t> > >&);
- void PassSequence(const Sequence<int32_t> &);
- void PassNullableSequence(const Nullable< Sequence<int32_t> >&);
- void PassSequenceOfNullableInts(const Sequence<Nullable<int32_t> >&);
- void PassOptionalSequenceOfNullableInts(const Optional<Sequence<Nullable<int32_t> > > &);
- void PassOptionalNullableSequenceOfNullableInts(const Optional<Nullable<Sequence<Nullable<int32_t> > > > &);
- void ReceiveCastableObjectSequence(nsTArray< nsRefPtr<TestInterface> > &);
- void ReceiveNullableCastableObjectSequence(nsTArray< nsRefPtr<TestInterface> > &);
- void ReceiveCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&);
- void ReceiveNullableCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&);
- void ReceiveWeakCastableObjectSequence(nsTArray<TestInterface*> &);
- void ReceiveWeakNullableCastableObjectSequence(nsTArray<TestInterface*> &);
- void ReceiveWeakCastableObjectNullableSequence(Nullable< nsTArray<TestInterface*> >&);
- void ReceiveWeakNullableCastableObjectNullableSequence(Nullable< nsTArray<TestInterface*> >&);
- void PassCastableObjectSequence(const Sequence< OwningNonNull<TestInterface> >&);
- void PassNullableCastableObjectSequence(const Sequence< nsRefPtr<TestInterface> > &);
- void PassCastableObjectNullableSequence(const Nullable< Sequence< OwningNonNull<TestInterface> > >&);
- void PassNullableCastableObjectNullableSequence(const Nullable< Sequence< nsRefPtr<TestInterface> > >&);
- void PassOptionalSequence(const Optional<Sequence<int32_t> >&);
- void PassOptionalNullableSequence(const Optional<Nullable<Sequence<int32_t> > >&);
- void PassOptionalNullableSequenceWithDefaultValue(const Nullable< Sequence<int32_t> >&);
- void PassOptionalObjectSequence(const Optional<Sequence<OwningNonNull<TestInterface> > >&);
-
- void ReceiveStringSequence(nsTArray<nsString>&);
- void PassStringSequence(const Sequence<nsString>&);
-
- void ReceiveAnySequence(JSContext*, nsTArray<JS::Value>&);
- void ReceiveNullableAnySequence(JSContext*, Nullable<nsTArray<JS::Value> >);
-
- // Typed array types
- void PassArrayBuffer(ArrayBuffer&);
- void PassNullableArrayBuffer(ArrayBuffer*);
- void PassOptionalArrayBuffer(const Optional<ArrayBuffer>&);
- void PassOptionalNullableArrayBuffer(const Optional<ArrayBuffer*>&);
- void PassOptionalNullableArrayBufferWithDefaultValue(ArrayBuffer*);
- void PassArrayBufferView(ArrayBufferView&);
- void PassInt8Array(Int8Array&);
- void PassInt16Array(Int16Array&);
- void PassInt32Array(Int32Array&);
- void PassUint8Array(Uint8Array&);
- void PassUint16Array(Uint16Array&);
- void PassUint32Array(Uint32Array&);
- void PassUint8ClampedArray(Uint8ClampedArray&);
- void PassFloat32Array(Float32Array&);
- void PassFloat64Array(Float64Array&);
- JSObject* ReceiveUint8Array(JSContext*);
-
- // String types
- void PassString(const nsAString&);
- void PassNullableString(const nsAString&);
- void PassOptionalString(const Optional<nsAString>&);
- void PassOptionalStringWithDefaultValue(const nsAString&);
- void PassOptionalNullableString(const Optional<nsAString>&);
- void PassOptionalNullableStringWithDefaultValue(const nsAString&);
-
- // Enumarated types
- void PassEnum(TestEnum);
- void PassOptionalEnum(const Optional<TestEnum>&);
- void PassEnumWithDefault(TestEnum);
- TestEnum ReceiveEnum();
- TestEnum EnumAttribute();
- TestEnum ReadonlyEnumAttribute();
- void SetEnumAttribute(TestEnum);
-
- // Callback types
- void PassCallback(JSContext*, JSObject*);
- void PassNullableCallback(JSContext*, JSObject*);
- void PassOptionalCallback(JSContext*, const Optional<JSObject*>&);
- void PassOptionalNullableCallback(JSContext*, const Optional<JSObject*>&);
- void PassOptionalNullableCallbackWithDefaultValue(JSContext*, JSObject*);
- JSObject* ReceiveCallback(JSContext*);
- JSObject* ReceiveNullableCallback(JSContext*);
-
- // Any types
- void PassAny(JSContext*, JS::Value);
- void PassOptionalAny(JSContext*, const Optional<JS::Value>&);
- void PassAnyDefaultNull(JSContext*, JS::Value);
- JS::Value ReceiveAny(JSContext*);
-
- // object types
- void PassObject(JSContext*, JSObject&);
- void PassNullableObject(JSContext*, JSObject*);
- void PassOptionalObject(JSContext*, const Optional<NonNull<JSObject> >&);
- void PassOptionalNullableObject(JSContext*, const Optional<JSObject*>&);
- void PassOptionalNullableObjectWithDefaultValue(JSContext*, JSObject*);
- JSObject* ReceiveObject(JSContext*);
- JSObject* ReceiveNullableObject(JSContext*);
-
- // Union types
- void PassUnion(JSContext*, const ObjectOrLong& arg);
- void PassUnionWithNullable(JSContext*, const ObjectOrNullOrLong& arg)
- {
- ObjectOrLong returnValue;
- if (arg.IsNull()) {
- } else if (arg.IsObject()) {
- JSObject& obj = (JSObject&)arg.GetAsObject();
- JS_GetClass(&obj);
- //returnValue.SetAsObject(&obj);
- } else {
- int32_t i = arg.GetAsLong();
- i += 1;
- }
- }
- void PassNullableUnion(JSContext*, const Nullable<ObjectOrLong>&);
- void PassOptionalUnion(JSContext*, const Optional<ObjectOrLong>&);
- void PassOptionalNullableUnion(JSContext*, const Optional<Nullable<ObjectOrLong> >&);
- void PassOptionalNullableUnionWithDefaultValue(JSContext*, const Nullable<ObjectOrLong>&);
- //void PassUnionWithInterfaces(const TestInterfaceOrTestExternalInterface& arg);
- //void PassUnionWithInterfacesAndNullable(const TestInterfaceOrNullOrTestExternalInterface& arg);
- void PassUnionWithArrayBuffer(const ArrayBufferOrLong&);
- void PassUnionWithString(JSContext*, const StringOrObject&);
- //void PassUnionWithEnum(JSContext*, const TestEnumOrObject&);
- void PassUnionWithCallback(JSContext*, const TestCallbackOrLong&);
- void PassUnionWithObject(JSContext*, const ObjectOrLong&);
-
- // binaryNames tests
- void MethodRenamedTo();
- void MethodRenamedTo(int8_t);
- int8_t AttributeGetterRenamedTo();
- int8_t AttributeRenamedTo();
- void SetAttributeRenamedTo(int8_t);
-
- // Dictionary tests
- void PassDictionary(const Dict&);
- void PassOtherDictionary(const GrandparentDict&);
- void PassSequenceOfDictionaries(const Sequence<Dict>&);
- void PassDictionaryOrLong(const Dict&);
- void PassDictionaryOrLong(int32_t);
- void PassDictContainingDict(const DictContainingDict&);
- void PassDictContainingSequence(const DictContainingSequence&);
-
- // Typedefs
- void ExerciseTypedefInterfaces1(TestInterface&);
- already_AddRefed<TestInterface> ExerciseTypedefInterfaces2(TestInterface*);
- void ExerciseTypedefInterfaces3(TestInterface&);
-
- // Miscellania
- int32_t AttrWithLenientThis();
- void SetAttrWithLenientThis(int32_t);
-
- // Methods and properties imported via "implements"
- bool ImplementedProperty();
- void SetImplementedProperty(bool);
- void ImplementedMethod();
- bool ImplementedParentProperty();
- void SetImplementedParentProperty(bool);
- void ImplementedParentMethod();
- bool IndirectlyImplementedProperty();
- void SetIndirectlyImplementedProperty(bool);
- void IndirectlyImplementedMethod();
- uint32_t DiamondImplementedProperty();
-
- // Test EnforceRange/Clamp
- void DontEnforceRangeOrClamp(int8_t);
- void DoEnforceRange(int8_t);
- void DoClamp(int8_t);
-
-private:
- // We add signatures here that _could_ start matching if the codegen
- // got data types wrong. That way if it ever does we'll have a call
- // to these private deleted methods and compilation will fail.
- void SetReadonlyByte(int8_t) MOZ_DELETE;
- template<typename T>
- void SetWritableByte(T) MOZ_DELETE;
- template<typename T>
- void PassByte(T) MOZ_DELETE;
- template<typename T>
- void PassOptionalByte(const Optional<T>&) MOZ_DELETE;
- template<typename T>
- void PassOptionalByteWithDefault(T) MOZ_DELETE;
-
- void SetReadonlyShort(int16_t) MOZ_DELETE;
- template<typename T>
- void SetWritableShort(T) MOZ_DELETE;
- template<typename T>
- void PassShort(T) MOZ_DELETE;
- template<typename T>
- void PassOptionalShort(const Optional<T>&) MOZ_DELETE;
- template<typename T>
- void PassOptionalShortWithDefault(T) MOZ_DELETE;
-
- void SetReadonlyLong(int32_t) MOZ_DELETE;
- template<typename T>
- void SetWritableLong(T) MOZ_DELETE;
- template<typename T>
- void PassLong(T) MOZ_DELETE;
- template<typename T>
- void PassOptionalLong(const Optional<T>&) MOZ_DELETE;
- template<typename T>
- void PassOptionalLongWithDefault(T) MOZ_DELETE;
-
- void SetReadonlyLongLong(int64_t) MOZ_DELETE;
- template<typename T>
- void SetWritableLongLong(T) MOZ_DELETE;
- template<typename T>
- void PassLongLong(T) MOZ_DELETE;
- template<typename T>
- void PassOptionalLongLong(const Optional<T>&) MOZ_DELETE;
- template<typename T>
- void PassOptionalLongLongWithDefault(T) MOZ_DELETE;
-
- void SetReadonlyOctet(uint8_t) MOZ_DELETE;
- template<typename T>
- void SetWritableOctet(T) MOZ_DELETE;
- template<typename T>
- void PassOctet(T) MOZ_DELETE;
- template<typename T>
- void PassOptionalOctet(const Optional<T>&) MOZ_DELETE;
- template<typename T>
- void PassOptionalOctetWithDefault(T) MOZ_DELETE;
-
- void SetReadonlyUnsignedShort(uint16_t) MOZ_DELETE;
- template<typename T>
- void SetWritableUnsignedShort(T) MOZ_DELETE;
- template<typename T>
- void PassUnsignedShort(T) MOZ_DELETE;
- template<typename T>
- void PassOptionalUnsignedShort(const Optional<T>&) MOZ_DELETE;
- template<typename T>
- void PassOptionalUnsignedShortWithDefault(T) MOZ_DELETE;
-
- void SetReadonlyUnsignedLong(uint32_t) MOZ_DELETE;
- template<typename T>
- void SetWritableUnsignedLong(T) MOZ_DELETE;
- template<typename T>
- void PassUnsignedLong(T) MOZ_DELETE;
- template<typename T>
- void PassOptionalUnsignedLong(const Optional<T>&) MOZ_DELETE;
- template<typename T>
- void PassOptionalUnsignedLongWithDefault(T) MOZ_DELETE;
-
- void SetReadonlyUnsignedLongLong(uint64_t) MOZ_DELETE;
- template<typename T>
- void SetWritableUnsignedLongLong(T) MOZ_DELETE;
- template<typename T>
- void PassUnsignedLongLong(T) MOZ_DELETE;
- template<typename T>
- void PassOptionalUnsignedLongLong(const Optional<T>&) MOZ_DELETE;
- template<typename T>
- void PassOptionalUnsignedLongLongWithDefault(T) MOZ_DELETE;
-
- // Enforce that only const things are passed for sequences
- void PassSequence(Sequence<int32_t> &) MOZ_DELETE;
- void PassNullableSequence(Nullable< Sequence<int32_t> >&) MOZ_DELETE;
- void PassOptionalNullableSequenceWithDefaultValue(Nullable< Sequence<int32_t> >&) MOZ_DELETE;
-
- // Enforce that only const things are passed for optional
- void PassOptionalByte(Optional<int8_t>&) MOZ_DELETE;
- void PassOptionalNullableByte(Optional<Nullable<int8_t> >&) MOZ_DELETE;
- void PassOptionalShort(Optional<int16_t>&) MOZ_DELETE;
- void PassOptionalLong(Optional<int32_t>&) MOZ_DELETE;
- void PassOptionalLongLong(Optional<int64_t>&) MOZ_DELETE;
- void PassOptionalOctet(Optional<uint8_t>&) MOZ_DELETE;
- void PassOptionalUnsignedShort(Optional<uint16_t>&) MOZ_DELETE;
- void PassOptionalUnsignedLong(Optional<uint32_t>&) MOZ_DELETE;
- void PassOptionalUnsignedLongLong(Optional<uint64_t>&) MOZ_DELETE;
- void PassOptionalSelf(Optional<TestInterface*> &) MOZ_DELETE;
- void PassOptionalNonNullSelf(Optional<NonNull<TestInterface> >&) MOZ_DELETE;
- void PassOptionalOther(Optional<TestNonCastableInterface*>&);
- void PassOptionalNonNullOther(Optional<NonNull<TestNonCastableInterface> >&);
- void PassOptionalExternal(Optional<TestExternalInterface*>&) MOZ_DELETE;
- void PassOptionalNonNullExternal(Optional<TestExternalInterface*>&) MOZ_DELETE;
- void PassOptionalSequence(Optional<Sequence<int32_t> >&) MOZ_DELETE;
- void PassOptionalNullableSequence(Optional<Nullable<Sequence<int32_t> > >&) MOZ_DELETE;
- void PassOptionalObjectSequence(Optional<Sequence<OwningNonNull<TestInterface> > >&) MOZ_DELETE;
- void PassOptionalArrayBuffer(Optional<ArrayBuffer>&) MOZ_DELETE;
- void PassOptionalNullableArrayBuffer(Optional<ArrayBuffer*>&) MOZ_DELETE;
- void PassOptionalEnum(Optional<TestEnum>&) MOZ_DELETE;
- void PassOptionalCallback(JSContext*, Optional<JSObject*>&) MOZ_DELETE;
- void PassOptionalNullableCallback(JSContext*, Optional<JSObject*>&) MOZ_DELETE;
- void PassOptionalAny(Optional<JS::Value>&) MOZ_DELETE;
-
- // And test that string stuff is always const
- void PassString(nsAString&) MOZ_DELETE;
- void PassNullableString(nsAString&) MOZ_DELETE;
- void PassOptionalString(Optional<nsAString>&) MOZ_DELETE;
- void PassOptionalStringWithDefaultValue(nsAString&) MOZ_DELETE;
- void PassOptionalNullableString(Optional<nsAString>&) MOZ_DELETE;
- void PassOptionalNullableStringWithDefaultValue(nsAString&) MOZ_DELETE;
-
-};
-
-class TestIndexedGetterInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-
- uint32_t IndexedGetter(uint32_t, bool&);
- uint32_t IndexedGetter(uint32_t&) MOZ_DELETE;
- uint32_t Item(uint32_t&);
- uint32_t Item(uint32_t, bool&) MOZ_DELETE;
- uint32_t Length();
-};
-
-class TestNamedGetterInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-
- void NamedGetter(const nsAString&, bool&, nsAString&);
-};
-
-class TestIndexedAndNamedGetterInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-
- uint32_t IndexedGetter(uint32_t, bool&);
- void NamedGetter(const nsAString&, bool&, nsAString&);
- void NamedItem(const nsAString&, nsAString&);
- uint32_t Length();
-};
-
-class TestIndexedSetterInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-
- void IndexedSetter(uint32_t, const nsAString&);
- void SetItem(uint32_t, const nsAString&);
-};
-
-class TestNamedSetterInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-
- void NamedSetter(const nsAString&, TestIndexedSetterInterface&);
-};
-
-class TestIndexedAndNamedSetterInterface : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_ISUPPORTS
-
- // We need a GetParentObject to make binding codegen happy
- virtual nsISupports* GetParentObject();
-
- void IndexedSetter(uint32_t, TestIndexedSetterInterface&);
- void NamedSetter(const nsAString&, TestIndexedSetterInterface&);
- void SetNamedItem(const nsAString&, TestIndexedSetterInterface&);
-};
-
-class TestIndexedAndNamedGetterAndSetterInterface : public TestIndexedSetterInterface
-{
-public:
- uint32_t IndexedGetter(uint32_t, bool&);
- uint32_t Item(uint32_t);
- void NamedGetter(const nsAString&, bool&, nsAString&);
- void NamedItem(const nsAString&, nsAString&);
- void IndexedSetter(uint32_t, int32_t&);
- void IndexedSetter(uint32_t, const nsAString&) MOZ_DELETE;
- void NamedSetter(const nsAString&, const nsAString&);
- void Stringify(nsAString&);
- uint32_t Length();
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif /* TestBindingHeader_h */
diff --git a/src/components/script/dom/bindings/codegen/test/TestCodeGen.webidl b/src/components/script/dom/bindings/codegen/test/TestCodeGen.webidl
deleted file mode 100644
index 8c2b3c1b6b4..00000000000
--- a/src/components/script/dom/bindings/codegen/test/TestCodeGen.webidl
+++ /dev/null
@@ -1,442 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-typedef long myLong;
-typedef TestInterface AnotherNameForTestInterface;
-typedef TestInterface? NullableTestInterface;
-
-interface TestExternalInterface;
-
-interface TestNonCastableInterface {
-};
-
-callback interface TestCallbackInterface {
- readonly attribute long foo;
- void doSomething();
-};
-
-enum TestEnum {
- "a",
- "b"
-};
-
-callback TestCallback = void();
-
-TestInterface implements ImplementedInterface;
-
-// This interface is only for use in the constructor below
-interface OnlyForUseInConstructor {
-};
-
-[Constructor,
- Constructor(DOMString str),
- Constructor(unsigned long num, boolean? bool),
- Constructor(TestInterface? iface),
- Constructor(TestNonCastableInterface iface)
- // , Constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3)
- ]
-interface TestInterface {
- // Integer types
- // XXXbz add tests for throwing versions of all the integer stuff
- readonly attribute byte readonlyByte;
- attribute byte writableByte;
- void passByte(byte arg);
- byte receiveByte();
- void passOptionalByte(optional byte arg);
- void passOptionalByteWithDefault(optional byte arg = 0);
- void passNullableByte(byte? arg);
- void passOptionalNullableByte(optional byte? arg);
-
- readonly attribute short readonlyShort;
- attribute short writableShort;
- void passShort(short arg);
- short receiveShort();
- void passOptionalShort(optional short arg);
- void passOptionalShortWithDefault(optional short arg = 5);
-
- readonly attribute long readonlyLong;
- attribute long writableLong;
- void passLong(long arg);
- long receiveLong();
- void passOptionalLong(optional long arg);
- void passOptionalLongWithDefault(optional long arg = 7);
-
- readonly attribute long long readonlyLongLong;
- attribute long long writableLongLong;
- void passLongLong(long long arg);
- long long receiveLongLong();
- void passOptionalLongLong(optional long long arg);
- void passOptionalLongLongWithDefault(optional long long arg = -12);
-
- readonly attribute octet readonlyOctet;
- attribute octet writableOctet;
- void passOctet(octet arg);
- octet receiveOctet();
- void passOptionalOctet(optional octet arg);
- void passOptionalOctetWithDefault(optional octet arg = 19);
-
- readonly attribute unsigned short readonlyUnsignedShort;
- attribute unsigned short writableUnsignedShort;
- void passUnsignedShort(unsigned short arg);
- unsigned short receiveUnsignedShort();
- void passOptionalUnsignedShort(optional unsigned short arg);
- void passOptionalUnsignedShortWithDefault(optional unsigned short arg = 2);
-
- readonly attribute unsigned long readonlyUnsignedLong;
- attribute unsigned long writableUnsignedLong;
- void passUnsignedLong(unsigned long arg);
- unsigned long receiveUnsignedLong();
- void passOptionalUnsignedLong(optional unsigned long arg);
- void passOptionalUnsignedLongWithDefault(optional unsigned long arg = 6);
-
- readonly attribute unsigned long long readonlyUnsignedLongLong;
- attribute unsigned long long writableUnsignedLongLong;
- void passUnsignedLongLong(unsigned long long arg);
- unsigned long long receiveUnsignedLongLong();
- void passOptionalUnsignedLongLong(optional unsigned long long arg);
- void passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 17);
-
- // Castable interface types
- // XXXbz add tests for throwing versions of all the castable interface stuff
- TestInterface receiveSelf();
- TestInterface? receiveNullableSelf();
- TestInterface receiveWeakSelf();
- TestInterface? receiveWeakNullableSelf();
- // A verstion to test for casting to TestInterface&
- void passSelf(TestInterface arg);
- // A version we can use to test for the exact type passed in
- void passSelf2(TestInterface arg);
- void passNullableSelf(TestInterface? arg);
- attribute TestInterface nonNullSelf;
- attribute TestInterface? nullableSelf;
- // Optional arguments
- void passOptionalSelf(optional TestInterface? arg);
- void passOptionalNonNullSelf(optional TestInterface arg);
- void passOptionalSelfWithDefault(optional TestInterface? arg = null);
-
- // Non-wrapper-cache interface types
- [Creator]
- TestNonWrapperCacheInterface receiveNonWrapperCacheInterface();
- [Creator]
- TestNonWrapperCacheInterface? receiveNullableNonWrapperCacheInterface();
- [Creator]
- sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
- [Creator]
- sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
- [Creator]
- sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
- [Creator]
- sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
-
- // Non-castable interface types
- TestNonCastableInterface receiveOther();
- TestNonCastableInterface? receiveNullableOther();
- TestNonCastableInterface receiveWeakOther();
- TestNonCastableInterface? receiveWeakNullableOther();
- // A verstion to test for casting to TestNonCastableInterface&
- void passOther(TestNonCastableInterface arg);
- // A version we can use to test for the exact type passed in
- void passOther2(TestNonCastableInterface arg);
- void passNullableOther(TestNonCastableInterface? arg);
- attribute TestNonCastableInterface nonNullOther;
- attribute TestNonCastableInterface? nullableOther;
- // Optional arguments
- void passOptionalOther(optional TestNonCastableInterface? arg);
- void passOptionalNonNullOther(optional TestNonCastableInterface arg);
- void passOptionalOtherWithDefault(optional TestNonCastableInterface? arg = null);
-
- // External interface types
- TestExternalInterface receiveExternal();
- TestExternalInterface? receiveNullableExternal();
- TestExternalInterface receiveWeakExternal();
- TestExternalInterface? receiveWeakNullableExternal();
- // A verstion to test for casting to TestExternalInterface&
- void passExternal(TestExternalInterface arg);
- // A version we can use to test for the exact type passed in
- void passExternal2(TestExternalInterface arg);
- void passNullableExternal(TestExternalInterface? arg);
- attribute TestExternalInterface nonNullExternal;
- attribute TestExternalInterface? nullableExternal;
- // Optional arguments
- void passOptionalExternal(optional TestExternalInterface? arg);
- void passOptionalNonNullExternal(optional TestExternalInterface arg);
- void passOptionalExternalWithDefault(optional TestExternalInterface? arg = null);
-
- // Callback interface types
- TestCallbackInterface receiveCallbackInterface();
- TestCallbackInterface? receiveNullableCallbackInterface();
- TestCallbackInterface receiveWeakCallbackInterface();
- TestCallbackInterface? receiveWeakNullableCallbackInterface();
- // A verstion to test for casting to TestCallbackInterface&
- void passCallbackInterface(TestCallbackInterface arg);
- // A version we can use to test for the exact type passed in
- void passCallbackInterface2(TestCallbackInterface arg);
- void passNullableCallbackInterface(TestCallbackInterface? arg);
- attribute TestCallbackInterface nonNullCallbackInterface;
- attribute TestCallbackInterface? nullableCallbackInterface;
- // Optional arguments
- void passOptionalCallbackInterface(optional TestCallbackInterface? arg);
- void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
- void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
-
- // Miscellaneous interface tests
- IndirectlyImplementedInterface receiveConsequentialInterface();
- void passConsequentialInterface(IndirectlyImplementedInterface arg);
-
- // Sequence types
- sequence<long> receiveSequence();
- sequence<long>? receiveNullableSequence();
- sequence<long?> receiveSequenceOfNullableInts();
- sequence<long?>? receiveNullableSequenceOfNullableInts();
- void passSequence(sequence<long> arg);
- void passNullableSequence(sequence<long>? arg);
- void passSequenceOfNullableInts(sequence<long?> arg);
- void passOptionalSequenceOfNullableInts(optional sequence<long?> arg);
- void passOptionalNullableSequenceOfNullableInts(optional sequence<long?>? arg);
- sequence<TestInterface> receiveCastableObjectSequence();
- sequence<TestInterface?> receiveNullableCastableObjectSequence();
- sequence<TestInterface>? receiveCastableObjectNullableSequence();
- sequence<TestInterface?>? receiveNullableCastableObjectNullableSequence();
- sequence<TestInterface> receiveWeakCastableObjectSequence();
- sequence<TestInterface?> receiveWeakNullableCastableObjectSequence();
- sequence<TestInterface>? receiveWeakCastableObjectNullableSequence();
- sequence<TestInterface?>? receiveWeakNullableCastableObjectNullableSequence();
- void passCastableObjectSequence(sequence<TestInterface> arg);
- void passNullableCastableObjectSequence(sequence<TestInterface?> arg);
- void passCastableObjectNullableSequence(sequence<TestInterface>? arg);
- void passNullableCastableObjectNullableSequence(sequence<TestInterface?>? arg);
- void passOptionalSequence(optional sequence<long> arg);
- void passOptionalNullableSequence(optional sequence<long>? arg);
- void passOptionalNullableSequenceWithDefaultValue(optional sequence<long>? arg = null);
- void passOptionalObjectSequence(optional sequence<TestInterface> arg);
-
- sequence<DOMString> receiveStringSequence();
- void passStringSequence(sequence<DOMString> arg);
-
- sequence<any> receiveAnySequence();
- sequence<any>? receiveNullableAnySequence();
-
- // Typed array types
- void passArrayBuffer(ArrayBuffer arg);
- void passNullableArrayBuffer(ArrayBuffer? arg);
- void passOptionalArrayBuffer(optional ArrayBuffer arg);
- void passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
- void passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg= null);
- void passArrayBufferView(ArrayBufferView arg);
- void passInt8Array(Int8Array arg);
- void passInt16Array(Int16Array arg);
- void passInt32Array(Int32Array arg);
- void passUint8Array(Uint8Array arg);
- void passUint16Array(Uint16Array arg);
- void passUint32Array(Uint32Array arg);
- void passUint8ClampedArray(Uint8ClampedArray arg);
- void passFloat32Array(Float32Array arg);
- void passFloat64Array(Float64Array arg);
- Uint8Array receiveUint8Array();
-
- // String types
- void passString(DOMString arg);
- void passNullableString(DOMString? arg);
- void passOptionalString(optional DOMString arg);
- void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
- void passOptionalNullableString(optional DOMString? arg);
- void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
-
- // Enumerated types
- void passEnum(TestEnum arg);
- // No support for nullable enums yet
- // void passNullableEnum(TestEnum? arg);
- void passOptionalEnum(optional TestEnum arg);
- void passEnumWithDefault(optional TestEnum arg = "a");
- // void passOptionalNullableEnum(optional TestEnum? arg);
- // void passOptionalNullableEnumWithDefaultValue(optional TestEnum? arg = null);
- TestEnum receiveEnum();
- attribute TestEnum enumAttribute;
- readonly attribute TestEnum readonlyEnumAttribute;
-
- // Callback types
- void passCallback(TestCallback arg);
- void passNullableCallback(TestCallback? arg);
- void passOptionalCallback(optional TestCallback arg);
- void passOptionalNullableCallback(optional TestCallback? arg);
- void passOptionalNullableCallbackWithDefaultValue(optional TestCallback? arg = null);
- TestCallback receiveCallback();
- TestCallback? receiveNullableCallback();
-
- // Any types
- void passAny(any arg);
- void passOptionalAny(optional any arg);
- void passAnyDefaultNull(optional any arg = null);
- any receiveAny();
-
- // object types
- void passObject(object arg);
- void passNullableObject(object? arg);
- void passOptionalObject(optional object arg);
- void passOptionalNullableObject(optional object? arg);
- void passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
- object receiveObject();
- object? receiveNullableObject();
-
- // Union types
- void passUnion((object or long) arg);
- void passUnionWithNullable((object? or long) arg);
- void passNullableUnion((object or long)? arg);
- void passOptionalUnion(optional (object or long) arg);
- void passOptionalNullableUnion(optional (object or long)? arg);
- void passOptionalNullableUnionWithDefaultValue(optional (object or long)? arg = null);
- //void passUnionWithInterfaces((TestInterface or TestExternalInterface) arg);
- //void passUnionWithInterfacesAndNullable((TestInterface? or TestExternalInterface) arg);
- //void passUnionWithSequence((sequence<object> or long) arg);
- void passUnionWithArrayBuffer((ArrayBuffer or long) arg);
- void passUnionWithString((DOMString or object) arg);
- //void passUnionWithEnum((TestEnum or object) arg);
- void passUnionWithCallback((TestCallback or long) arg);
- void passUnionWithObject((object or long) arg);
- //void passUnionWithDict((Dict or long) arg);
-
- // binaryNames tests
- void methodRenamedFrom();
- void methodRenamedFrom(byte argument);
- readonly attribute byte attributeGetterRenamedFrom;
- attribute byte attributeRenamedFrom;
-
- void passDictionary(optional Dict x);
- void passOtherDictionary(optional GrandparentDict x);
- void passSequenceOfDictionaries(sequence<Dict> x);
- void passDictionaryOrLong(optional Dict x);
- void passDictionaryOrLong(long x);
-
- void passDictContainingDict(optional DictContainingDict arg);
- void passDictContainingSequence(optional DictContainingSequence arg);
-
- // EnforceRange/Clamp tests
- void dontEnforceRangeOrClamp(byte arg);
- void doEnforceRange([EnforceRange] byte arg);
- void doClamp([Clamp] byte arg);
-
- // Typedefs
- const myLong myLongConstant = 5;
- void exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
- AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
- void exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
-
- // Miscellania
- [LenientThis] attribute long attrWithLenientThis;
-};
-
-interface TestNonWrapperCacheInterface {
-};
-
-interface ImplementedInterfaceParent {
- void implementedParentMethod();
- attribute boolean implementedParentProperty;
-
- const long implementedParentConstant = 8;
-};
-
-ImplementedInterfaceParent implements IndirectlyImplementedInterface;
-
-[NoInterfaceObject]
-interface IndirectlyImplementedInterface {
- void indirectlyImplementedMethod();
- attribute boolean indirectlyImplementedProperty;
-
- const long indirectlyImplementedConstant = 9;
-};
-
-interface ImplementedInterface : ImplementedInterfaceParent {
- void implementedMethod();
- attribute boolean implementedProperty;
-
- const long implementedConstant = 5;
-};
-
-interface DiamondImplements {
- readonly attribute long diamondImplementedProperty;
-};
-interface DiamondBranch1A {
-};
-interface DiamondBranch1B {
-};
-interface DiamondBranch2A : DiamondImplements {
-};
-interface DiamondBranch2B : DiamondImplements {
-};
-TestInterface implements DiamondBranch1A;
-TestInterface implements DiamondBranch1B;
-TestInterface implements DiamondBranch2A;
-TestInterface implements DiamondBranch2B;
-DiamondBranch1A implements DiamondImplements;
-DiamondBranch1B implements DiamondImplements;
-
-dictionary Dict : ParentDict {
- TestEnum someEnum;
- long x;
- long a;
- long b = 8;
- long z = 9;
- DOMString str;
- DOMString empty = "";
- TestEnum otherEnum = "b";
- DOMString otherStr = "def";
- DOMString? yetAnotherStr = null;
-};
-
-dictionary ParentDict : GrandparentDict {
- long c = 5;
- TestInterface someInterface;
- TestExternalInterface someExternalInterface;
-};
-
-dictionary DictContainingDict {
- Dict memberDict;
-};
-
-dictionary DictContainingSequence {
- sequence<long> ourSequence;
-};
-
-interface TestIndexedGetterInterface {
- getter long item(unsigned long index);
- [Infallible]
- readonly attribute unsigned long length;
-};
-
-interface TestNamedGetterInterface {
- getter DOMString (DOMString name);
-};
-
-interface TestIndexedAndNamedGetterInterface {
- getter long (unsigned long index);
- getter DOMString namedItem(DOMString name);
- [Infallible]
- readonly attribute unsigned long length;
-};
-
-interface TestIndexedSetterInterface {
- setter creator void setItem(unsigned long index, DOMString item);
-};
-
-interface TestNamedSetterInterface {
- setter creator void (DOMString name, TestIndexedSetterInterface item);
-};
-
-interface TestIndexedAndNamedSetterInterface {
- setter creator void (unsigned long index, TestIndexedSetterInterface item);
- setter creator void setNamedItem(DOMString name, TestIndexedSetterInterface item);
-};
-
-interface TestIndexedAndNamedGetterAndSetterInterface : TestIndexedSetterInterface {
- getter long item(unsigned long index);
- getter DOMString namedItem(DOMString name);
- setter creator void (unsigned long index, long item);
- setter creator void (DOMString name, DOMString item);
- [Infallible]
- stringifier DOMString ();
- [Infallible]
- readonly attribute unsigned long length;
-};
diff --git a/src/components/script/dom/bindings/codegen/test/TestDictionary.webidl b/src/components/script/dom/bindings/codegen/test/TestDictionary.webidl
deleted file mode 100644
index 3dd91bd6500..00000000000
--- a/src/components/script/dom/bindings/codegen/test/TestDictionary.webidl
+++ /dev/null
@@ -1,9 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-dictionary GrandparentDict {
- double someNum;
-}; \ No newline at end of file
diff --git a/src/components/script/dom/bindings/codegen/test/TestTypedef.webidl b/src/components/script/dom/bindings/codegen/test/TestTypedef.webidl
deleted file mode 100644
index 7f758c79e8f..00000000000
--- a/src/components/script/dom/bindings/codegen/test/TestTypedef.webidl
+++ /dev/null
@@ -1,7 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-typedef TestInterface YetAnotherNameForTestInterface;
diff --git a/src/components/script/dom/bindings/codegen/test/file_bug775543.html b/src/components/script/dom/bindings/codegen/test/file_bug775543.html
deleted file mode 100644
index ee8c14c4d9c..00000000000
--- a/src/components/script/dom/bindings/codegen/test/file_bug775543.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-<script>
-worker = new Worker("a");
-</script>
-</body>
diff --git a/src/components/script/dom/bindings/codegen/test/forOf_iframe.html b/src/components/script/dom/bindings/codegen/test/forOf_iframe.html
deleted file mode 100644
index 91417aba0e8..00000000000
--- a/src/components/script/dom/bindings/codegen/test/forOf_iframe.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>iframe content for test_forOf_iframe.html</title>
-</head>
-<body>
- <div id="basket">
- <span id="egg0"></span>
- <span id="egg1"><span id="duckling1"></span></span>
- <span id="egg2"></span>
- </div>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_InstanceOf.html b/src/components/script/dom/bindings/codegen/test/test_InstanceOf.html
deleted file mode 100644
index 3a5a76b1b21..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_InstanceOf.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=748983
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 748983</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=748983">Mozilla Bug 748983</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 748983 **/
-ok(document instanceof EventTarget, "document is an event target")
-ok(new XMLHttpRequest() instanceof XMLHttpRequest, "instanceof should work on XHR");
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_bug773326.html b/src/components/script/dom/bindings/codegen/test/test_bug773326.html
deleted file mode 100644
index 2e3b1ea304d..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_bug773326.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>Test for Bug 773326</title>
-<script src=/resources/testharness.js></script>
-<script src=/resources/testharnessreport.js></script>
-<div id=log></div>
-<script>
-test(function() {
- new Worker("data:text/javascript,new XMLHttpRequest(42)");
-}, "Should not crash")
-</script>
diff --git a/src/components/script/dom/bindings/codegen/test/test_bug775543.html b/src/components/script/dom/bindings/codegen/test/test_bug775543.html
deleted file mode 100644
index d8df05f630f..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_bug775543.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=775543
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 775543</title>
- <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=775543">Mozilla Bug 775543</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-<iframe id="t" src="http://example.org/tests/dom/bindings/test/file_bug775543.html" onload="test();"></iframe>
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 775543 **/
-
-function test()
-{
- var a = XPCNativeWrapper(document.getElementById("t").contentWindow.wrappedJSObject.worker);
- isnot(XPCNativeWrapper.unwrap(a), a, "XPCNativeWrapper(Worker) should be an Xray wrapper");
- a.toString();
- ok(true, "Shouldn't crash when calling a method on an Xray wrapper around a worker");
- SimpleTest.finish();
-}
-
-SimpleTest.waitForExplicitFinish();
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_bug788369.html b/src/components/script/dom/bindings/codegen/test/test_bug788369.html
deleted file mode 100644
index 787bd28fe34..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_bug788369.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=788369
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 788369</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=788369">Mozilla Bug 788369</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 788369 **/
-try {
- var xhr = new(window.ActiveXObject || XMLHttpRequest)("Microsoft.XMLHTTP");
- ok(xhr instanceof XMLHttpRequest, "Should have an XHR object");
-} catch (e) {
- ok(false, "Should not throw exception when constructing: " + e);
-}
-</script>
-</pre>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_enums.html b/src/components/script/dom/bindings/codegen/test/test_enums.html
deleted file mode 100644
index e5dc519a0c9..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_enums.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>Enums</title>
-<script src=/resources/testharness.js></script>
-<script src=/resources/testharnessreport.js></script>
-<div id=log></div>
-<script>
-test(function() {
- var xhr = new XMLHttpRequest();
- xhr.open("get", "foo")
- assert_equals(xhr.responseType, "");
- xhr.responseType = "foo";
- assert_equals(xhr.responseType, "");
-}, "Assigning an invalid value to an enum attribute should not throw.");
-</script>
diff --git a/src/components/script/dom/bindings/codegen/test/test_forOf.html b/src/components/script/dom/bindings/codegen/test/test_forOf.html
deleted file mode 100644
index b1a3032a385..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_forOf.html
+++ /dev/null
@@ -1,94 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=725907
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 725907</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=725907">Mozilla Bug 725907</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<div id="basket">
- <span id="egg0"></span>
- <span id="egg1"><span id="duckling1"></span></span>
- <span id="egg2"></span>
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 725907 **/
-
-function runTestsForDocument(document, msgSuffix) {
- function is(a, b, msg) { SimpleTest.is(a, b, msg + msgSuffix); }
- function isnot(a, b, msg) { SimpleTest.isnot(a, b, msg + msgSuffix); }
-
- var basket = document.getElementById("basket");
- var egg3 = document.createElement("span");
- egg3.id = "egg3";
-
- var log = '';
- for (var x of basket.childNodes) {
- if (x.nodeType != x.TEXT_NODE)
- log += x.id + ";";
- }
- is(log, "egg0;egg1;egg2;", "'for (x of div.childNodes)' should iterate over child nodes");
-
- log = '';
- for (var x of basket.childNodes) {
- if (x.nodeType != x.TEXT_NODE) {
- log += x.id + ";";
- if (x.id == "egg1")
- basket.appendChild(egg3);
- }
- }
- is(log, "egg0;egg1;egg2;egg3;", "'for (x of div.childNodes)' should see elements added during iteration");
-
- var iter1 = basket.childNodes.iterator();
- var iter2 = basket.childNodes.iterator();
- isnot(iter1, iter2, "nodelist.iterator() returns a new iterator each time");
-
- log = '';
- basket.appendChild(document.createTextNode("some text"));
- for (var x of basket.children)
- log += x.id + ";";
- is(log, "egg0;egg1;egg2;egg3;", "'for (x of div.children)' should iterate over child elements");
-
- var iter1 = basket.children.iterator();
- var iter2 = basket.children.iterator();
- isnot(iter1, iter2, ".iterator() returns a new iterator each time");
-
- var count = 0;
- for (var x of document.getElementsByClassName("hazardous-materials"))
- count++;
- is(count, 0, "'for (x of emptyNodeList)' loop should run zero times");
-
- var log = '';
- for (var x of document.querySelectorAll("span"))
- log += x.id + ";";
- is(log, "egg0;egg1;duckling1;egg2;egg3;", "for-of loop should work with a querySelectorAll() NodeList");
-}
-
-/* All the tests run twice. First, in this document, so without any wrappers. */
-runTestsForDocument(document, "");
-
-/* And once using the document of an iframe, so working with cross-compartment wrappers. */
-SimpleTest.waitForExplicitFinish();
-function iframeLoaded(iframe) {
- runTestsForDocument(iframe.contentWindow.document, " (in iframe)");
- SimpleTest.finish();
-}
-
-</script>
-
-<iframe src="forOf_iframe.html" onload="iframeLoaded(this)"></iframe>
-
-</pre>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_integers.html b/src/components/script/dom/bindings/codegen/test/test_integers.html
deleted file mode 100644
index 6799fd791a8..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_integers.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8">
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<p id="display"></p>
-<div id="content" style="display: none">
- <canvas id="c" width="1" height="1"></canvas>
-</div>
-<pre id="test">
-<script type="application/javascript">
-
- function testInt64NonFinite(arg) {
- // We can use a WebGLRenderingContext to test conversion to 64-bit signed
- // ints edge cases.
- try {
- var gl = $("c").getContext("experimental-webgl");
- } catch (ex) {
- // No WebGL support on MacOS 10.5. Just skip this test
- todo(false, "WebGL not supported");
- return;
- }
- is(gl.getError(), 0, "Should not start in an error state");
-
- var b = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, b);
-
- var a = new Float32Array(1);
- gl.bufferData(gl.ARRAY_BUFFER, a, gl.STATIC_DRAW);
-
- gl.bufferSubData(gl.ARRAY_BUFFER, arg, a);
-
- is(gl.getError(), 0, "Should have treated non-finite double as 0");
- }
-
- testInt64NonFinite(NaN);
- testInt64NonFinite(Infinity);
- testInt64NonFinite(-Infinity);
-</script>
-</pre>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_interfaceToString.html b/src/components/script/dom/bindings/codegen/test/test_interfaceToString.html
deleted file mode 100644
index cf670bf2d54..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_interfaceToString.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=742156
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 742156</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=742156">Mozilla Bug 742156</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 742156 **/
-
-var nativeToString = ("" + String.replace).replace("replace", "EventTarget");
-try {
- var eventTargetToString = "" + EventTarget;
- is(eventTargetToString, nativeToString,
- "Stringifying a DOM interface object should return the same string" +
- "as stringifying a native function.");
-}
-catch (e) {
- ok(false, "Stringifying a DOM interface object shouldn't throw.");
-}
-
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_lookupGetter.html b/src/components/script/dom/bindings/codegen/test/test_lookupGetter.html
deleted file mode 100644
index 306ee4f643c..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_lookupGetter.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=462428
--->
-<head>
- <title>Test for Bug 462428</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462428">Mozilla Bug 462428</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 462428 **/
-var x = new XMLHttpRequest;
-x.open("GET", "");
-var getter = x.__lookupGetter__('readyState');
-ok(getter !== undefined, "But able to look it up the normal way");
-ok(!x.hasOwnProperty('readyState'), "property should still be on the prototype");
-
-var sawProp = false;
-for (var i in x) {
- if (i === "readyState") {
- sawProp = true;
- }
-}
-
-ok(sawProp, "property should be enumerable");
-
-is(getter.call(x), 1, "the getter actually works");
-
-Object.getPrototypeOf(x).__defineSetter__('readyState', function() {});
-is(getter.call(x), 1, "the getter works after defineSetter");
-
-is(x.responseType, "", "Should have correct responseType up front");
-var setter = x.__lookupSetter__('responseType');
-setter.call(x, "document");
-is(x.responseType, "document", "the setter is bound correctly");
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_sequence_wrapping.html b/src/components/script/dom/bindings/codegen/test/test_sequence_wrapping.html
deleted file mode 100644
index e4f18f9986c..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_sequence_wrapping.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=775852
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 775852</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=775852">Mozilla Bug 775852</a>
-<p id="display"></p>
-<div id="content" style="display: none">
- <canvas width="1" height="1" id="c"></canvas>
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 775852 **/
-function doTest() {
- try {
- var gl = $("c").getContext("experimental-webgl");
- } catch (e) {
- // No WebGL support on MacOS 10.5. Just skip this test
- todo(false, "WebGL not supported");
- return;
- }
- var setterCalled = false;
-
- extLength = gl.getSupportedExtensions().length;
- ok(extLength > 0,
- "This test won't work right if we have no supported extensions");
-
- Object.defineProperty(Array.prototype, "0",
- {
- set: function(val) {
- setterCalled = true;
- }
- });
-
- // Test that our property got defined correctly
- var arr = []
- arr[0] = 5;
- is(setterCalled, true, "Setter should be called when setting prop on array");
-
- setterCalled = false;
-
- is(gl.getSupportedExtensions().length, extLength,
- "We should still have the same number of extensions");
-
- is(setterCalled, false,
- "Setter should not be called when getting supported extensions");
-}
-doTest();
-</script>
-</pre>
-</body>
-</html>
diff --git a/src/components/script/dom/bindings/codegen/test/test_traceProtos.html b/src/components/script/dom/bindings/codegen/test/test_traceProtos.html
deleted file mode 100644
index 195876744d6..00000000000
--- a/src/components/script/dom/bindings/codegen/test/test_traceProtos.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=744772
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 744772</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=744772">Mozilla Bug 744772</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 744772 **/
-
-SimpleTest.waitForExplicitFinish();
-
-function callback() {
- new XMLHttpRequest().upload;
- ok(true, "Accessing unreferenced DOM interface objects shouldn't crash");
- SimpleTest.finish();
-}
-
-delete window.XMLHttpRequestUpload;
-SpecialPowers.exactGC(window, callback);
-
-</script>
-</pre>
-</body>
-</html>