mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Cargoify servo
This commit is contained in:
parent
db2f642c32
commit
c6ab60dbfc
1761 changed files with 8423 additions and 2294 deletions
200
components/script/dom/attr.rs
Normal file
200
components/script/dom/attr.rs
Normal file
|
@ -0,0 +1,200 @@
|
|||
/* 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/. */
|
||||
|
||||
use dom::bindings::codegen::Bindings::AttrBinding;
|
||||
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||
use dom::bindings::global::Window;
|
||||
use dom::bindings::js::{JS, JSRef, Temporary};
|
||||
use dom::bindings::trace::Traceable;
|
||||
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||
use dom::element::{Element, AttributeHandlers};
|
||||
use dom::node::Node;
|
||||
use dom::window::Window;
|
||||
use dom::virtualmethods::vtable_for;
|
||||
use servo_util::atom::Atom;
|
||||
use servo_util::namespace;
|
||||
use servo_util::namespace::Namespace;
|
||||
use servo_util::str::{DOMString, split_html_space_chars};
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::mem;
|
||||
use std::slice::Items;
|
||||
|
||||
pub enum AttrSettingType {
|
||||
FirstSetAttr,
|
||||
ReplacedAttr,
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Clone, Encodable)]
|
||||
pub enum AttrValue {
|
||||
StringAttrValue(DOMString),
|
||||
TokenListAttrValue(DOMString, Vec<Atom>),
|
||||
UIntAttrValue(DOMString, u32),
|
||||
AtomAttrValue(Atom),
|
||||
}
|
||||
|
||||
impl AttrValue {
|
||||
pub fn from_tokenlist(tokens: DOMString) -> AttrValue {
|
||||
let atoms = split_html_space_chars(tokens.as_slice())
|
||||
.map(|token| Atom::from_slice(token)).collect();
|
||||
TokenListAttrValue(tokens, atoms)
|
||||
}
|
||||
|
||||
pub fn from_u32(string: DOMString, default: u32) -> AttrValue {
|
||||
let result: u32 = from_str(string.as_slice()).unwrap_or(default);
|
||||
UIntAttrValue(string, result)
|
||||
}
|
||||
|
||||
pub fn from_atomic(string: DOMString) -> AttrValue {
|
||||
let value = Atom::from_slice(string.as_slice());
|
||||
AtomAttrValue(value)
|
||||
}
|
||||
|
||||
pub fn tokens<'a>(&'a self) -> Option<Items<'a, Atom>> {
|
||||
match *self {
|
||||
TokenListAttrValue(_, ref tokens) => Some(tokens.iter()),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Str for AttrValue {
|
||||
fn as_slice<'a>(&'a self) -> &'a str {
|
||||
match *self {
|
||||
StringAttrValue(ref value) |
|
||||
TokenListAttrValue(ref value, _) |
|
||||
UIntAttrValue(ref value, _) => value.as_slice(),
|
||||
AtomAttrValue(ref value) => value.as_slice(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
pub struct Attr {
|
||||
reflector_: Reflector,
|
||||
local_name: Atom,
|
||||
value: Traceable<RefCell<AttrValue>>,
|
||||
pub name: Atom,
|
||||
pub namespace: Namespace,
|
||||
pub prefix: Option<DOMString>,
|
||||
|
||||
/// the element that owns this attribute.
|
||||
owner: JS<Element>,
|
||||
}
|
||||
|
||||
impl Reflectable for Attr {
|
||||
fn reflector<'a>(&'a self) -> &'a Reflector {
|
||||
&self.reflector_
|
||||
}
|
||||
}
|
||||
|
||||
impl Attr {
|
||||
fn new_inherited(local_name: Atom, value: AttrValue,
|
||||
name: Atom, namespace: Namespace,
|
||||
prefix: Option<DOMString>, owner: &JSRef<Element>) -> Attr {
|
||||
Attr {
|
||||
reflector_: Reflector::new(),
|
||||
local_name: local_name,
|
||||
value: Traceable::new(RefCell::new(value)),
|
||||
name: name,
|
||||
namespace: namespace,
|
||||
prefix: prefix,
|
||||
owner: JS::from_rooted(owner),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(window: &JSRef<Window>, local_name: Atom, value: AttrValue,
|
||||
name: Atom, namespace: Namespace,
|
||||
prefix: Option<DOMString>, owner: &JSRef<Element>) -> Temporary<Attr> {
|
||||
let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner);
|
||||
reflect_dom_object(box attr, &Window(*window), AttrBinding::Wrap)
|
||||
}
|
||||
|
||||
pub fn set_value(&self, set_type: AttrSettingType, value: AttrValue) {
|
||||
let owner = self.owner.root();
|
||||
let node: &JSRef<Node> = NodeCast::from_ref(&*owner);
|
||||
let namespace_is_null = self.namespace == namespace::Null;
|
||||
|
||||
match set_type {
|
||||
ReplacedAttr => {
|
||||
if namespace_is_null {
|
||||
vtable_for(node).before_remove_attr(
|
||||
self.local_name(),
|
||||
self.value().as_slice().to_string())
|
||||
}
|
||||
}
|
||||
FirstSetAttr => {}
|
||||
}
|
||||
|
||||
*self.value.deref().borrow_mut() = value;
|
||||
|
||||
if namespace_is_null {
|
||||
vtable_for(node).after_set_attr(
|
||||
self.local_name(),
|
||||
self.value().as_slice().to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value<'a>(&'a self) -> Ref<'a, AttrValue> {
|
||||
self.value.deref().borrow()
|
||||
}
|
||||
|
||||
pub fn local_name<'a>(&'a self) -> &'a Atom {
|
||||
&self.local_name
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AttrMethods for JSRef<'a, Attr> {
|
||||
fn LocalName(&self) -> DOMString {
|
||||
self.local_name().as_slice().to_string()
|
||||
}
|
||||
|
||||
fn Value(&self) -> DOMString {
|
||||
self.value().as_slice().to_string()
|
||||
}
|
||||
|
||||
fn SetValue(&self, value: DOMString) {
|
||||
let owner = self.owner.root();
|
||||
let value = owner.deref().parse_attribute(
|
||||
&self.namespace, self.local_name(), value);
|
||||
self.set_value(ReplacedAttr, value);
|
||||
}
|
||||
|
||||
fn Name(&self) -> DOMString {
|
||||
self.name.as_slice().to_string()
|
||||
}
|
||||
|
||||
fn GetNamespaceURI(&self) -> Option<DOMString> {
|
||||
match self.namespace.to_str() {
|
||||
"" => None,
|
||||
url => Some(url.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn GetPrefix(&self) -> Option<DOMString> {
|
||||
self.prefix.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AttrHelpersForLayout {
|
||||
unsafe fn value_ref_forever(&self) -> &'static str;
|
||||
unsafe fn value_atom_forever(&self) -> Option<Atom>;
|
||||
}
|
||||
|
||||
impl AttrHelpersForLayout for Attr {
|
||||
unsafe fn value_ref_forever(&self) -> &'static str {
|
||||
// cast to point to T in RefCell<T> directly
|
||||
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(self.value.deref());
|
||||
value.as_slice()
|
||||
}
|
||||
|
||||
unsafe fn value_atom_forever(&self) -> Option<Atom> {
|
||||
// cast to point to T in RefCell<T> directly
|
||||
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(self.value.deref());
|
||||
match *value {
|
||||
AtomAttrValue(ref val) => Some(val.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
38
components/script/dom/bindings/DESIGN.md
Normal file
38
components/script/dom/bindings/DESIGN.md
Normal file
|
@ -0,0 +1,38 @@
|
|||
# The design of Garbage collected DOM
|
||||
|
||||
These are how Servo provides an object graph to SpiderMonkey's Garbage Collection.
|
||||
|
||||
## Construct
|
||||
When Servo creates a Rusty DOM object, the binding code creates a wrapper `JSObject` with SpiderMonkey, is correspond to each Rusty DOM Object. It’s produced and set to the Rusty object in `FooBinding::Wrap`.
|
||||
|
||||
In `FooBinding::Wrap`, the wrapper JSObject gets the pointer for Rusty Object to itself. And the same time, the wrapper `JSObject` are set to the Rusty Object’s `Reflector` field (All Rusty DOM objects have `dom::bindings::utils::Reflector` in their most basis field). These step are the “binding” work to create the relationship of both objects.
|
||||
|
||||
|
||||
## Trace object graph from SpiderMonkey GC.
|
||||
This is very tricky and magically mechanism helped by Rust Compiler.
|
||||
The outline is:
|
||||
|
||||
1. SpiderMonkey's GC calls `JSClass.trace` defined in `FooBinding` when marking phase. This JSClass is basis of each wrapper JSObject.
|
||||
2. `JSClass.trace` calls `Foo::trace()` defined in InhertTypes.rs.
|
||||
3. `Foo::trace()` calls `Foo::encode()`. This `encode()` method is derived by the annotation of `#[deriving(Encodable)]` for a Rust DOM Element struct.
|
||||
4. `Foo::encode()` calls `JS<T>::encode()` method of `JS<T>` which is contained to `Foo`’s member. So this is the compiler magic! Rust compiler generates [codes like this](https://github.com/mozilla/rust/blob/db5206c32a879d5058d6a5cdce39c13c763fbdd5/src/libsyntax/ext/deriving/encodable.rs) for all structs annotated `#[deriving(Encodable)]`. This is based on [the assumption](https://github.com/mozilla/servo/blob/54da52fa774ce2ee59fcf811af595bf292169ad8/src/components/script/dom/bindings/trace.rs#L16).
|
||||
5. `JS<T>::encode()` calls `dom::bindings::trace::trace_reflector()`.
|
||||
6. `trace_reflector()` fetches the reflector that is reachable from a Rust object, and notifies it to the GC with using JSTracer.
|
||||
7. This operation continues to the end of the graph.
|
||||
8. Finally, GC gets whether Rust object lives or not from JSObjects which is hold by Rust object.
|
||||
|
||||
|
||||
## Destruct
|
||||
When destructing DOM objects (wrapper JSObjects) by SpiderMonkey, SpiderMonkey calls the `JSClass.finalize()` which is basis of each wrapper `JSObject`s. This method refers each `FooBinding::_finalize()`.
|
||||
|
||||
In this function, the pointer of Rusty DOM Object that is contained in the wrapper JSObject is unwrapped, it cast to Rust owned pointer, and we assign its owned pointer to the empty local variable of `FooBinding::_finalize()`. Thus we can destruct the Rusty Object after we left from it.
|
||||
|
||||
|
||||
## Interact with Exact GC’s rooting
|
||||
For supporting SpiderMonkey’s exact GC rooting, we introduce [some types](https://github.com/mozilla/servo/wiki/Using-DOM-types):
|
||||
|
||||
- `JS<T>` is used for the DOM typed field in a DOM type structure. GC can trace them recursively while enclosing DOM object (maybe root) is alive.
|
||||
- `Temporary<T>` is used as a return value of functions returning DOM type. They are rooted while they are alive. But a retun value gets moved around. It’s breakable for the LIFO ordering constraint. Thus we need introduce `Root<T>`.
|
||||
- `Root<T>` contains the pointer to `JSObject` which the represented DOM type has. SpiderMonkey's conservative stack scanner scans its pointer and mark a pointed `JSObject` as GC root.
|
||||
- `JSRef` is just a reference to the value rooted by `Root<T>`.
|
||||
- `RootCollection` is used for dynamic checking about rooting satisfies LIFO ordering, because SpiderMonkey GC requres LIFO order (See also: [Exact Stack Rooting - Storing a GCPointer on the CStack](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting)).
|
156
components/script/dom/bindings/callback.rs
Normal file
156
components/script/dom/bindings/callback.rs
Normal file
|
@ -0,0 +1,156 @@
|
|||
/* 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/. */
|
||||
|
||||
//! Base classes to work with IDL callbacks.
|
||||
|
||||
use dom::bindings::js::JSRef;
|
||||
use dom::bindings::trace::Traceable;
|
||||
use dom::bindings::utils::{Reflectable, global_object_for_js_object};
|
||||
use js::jsapi::{JSContext, JSObject, JS_WrapObject, JS_ObjectIsCallable};
|
||||
use js::jsapi::JS_GetProperty;
|
||||
use js::jsval::{JSVal, UndefinedValue};
|
||||
|
||||
use std::ptr;
|
||||
|
||||
use serialize::{Encodable, Encoder};
|
||||
|
||||
/// The exception handling used for a call.
|
||||
pub enum ExceptionHandling {
|
||||
/// Report any exception and don't throw it to the caller code.
|
||||
ReportExceptions,
|
||||
/// Throw an exception to the caller code if the thrown exception is a
|
||||
/// binding object for a DOMError from the caller's scope, otherwise report
|
||||
/// it.
|
||||
RethrowContentExceptions,
|
||||
/// Throw any exception to the caller code.
|
||||
RethrowExceptions
|
||||
}
|
||||
|
||||
/// A common base class for representing IDL callback function types.
|
||||
#[deriving(Clone,PartialEq,Encodable)]
|
||||
pub struct CallbackFunction {
|
||||
object: CallbackObject
|
||||
}
|
||||
|
||||
impl CallbackFunction {
|
||||
pub fn new(callback: *mut JSObject) -> CallbackFunction {
|
||||
CallbackFunction {
|
||||
object: CallbackObject {
|
||||
callback: Traceable::new(callback)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A common base class for representing IDL callback interface types.
|
||||
#[deriving(Clone,PartialEq,Encodable)]
|
||||
pub struct CallbackInterface {
|
||||
object: CallbackObject
|
||||
}
|
||||
|
||||
/// A common base class for representing IDL callback function and
|
||||
/// callback interface types.
|
||||
#[allow(raw_pointer_deriving)]
|
||||
#[deriving(Clone,PartialEq,Encodable)]
|
||||
struct CallbackObject {
|
||||
/// The underlying `JSObject`.
|
||||
callback: Traceable<*mut JSObject>,
|
||||
}
|
||||
|
||||
/// A trait to be implemented by concrete IDL callback function and
|
||||
/// callback interface types.
|
||||
pub trait CallbackContainer {
|
||||
/// Create a new CallbackContainer object for the given `JSObject`.
|
||||
fn new(callback: *mut JSObject) -> Self;
|
||||
/// Returns the underlying `JSObject`.
|
||||
fn callback(&self) -> *mut JSObject;
|
||||
}
|
||||
|
||||
impl CallbackInterface {
|
||||
/// Returns the underlying `JSObject`.
|
||||
pub fn callback(&self) -> *mut JSObject {
|
||||
*self.object.callback
|
||||
}
|
||||
}
|
||||
|
||||
impl CallbackFunction {
|
||||
/// Returns the underlying `JSObject`.
|
||||
pub fn callback(&self) -> *mut JSObject {
|
||||
*self.object.callback
|
||||
}
|
||||
}
|
||||
|
||||
impl CallbackInterface {
|
||||
/// Create a new CallbackInterface object for the given `JSObject`.
|
||||
pub fn new(callback: *mut JSObject) -> CallbackInterface {
|
||||
CallbackInterface {
|
||||
object: CallbackObject {
|
||||
callback: Traceable::new(callback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the property with the given `name`, if it is a callable object,
|
||||
/// or `Err(())` otherwise. If it returns `Err(())`, a JSAPI exception is
|
||||
/// pending.
|
||||
pub fn GetCallableProperty(&self, cx: *mut JSContext, name: &str) -> Result<JSVal, ()> {
|
||||
let mut callable = UndefinedValue();
|
||||
unsafe {
|
||||
let name = name.to_c_str();
|
||||
if JS_GetProperty(cx, self.callback(), name.as_ptr(), &mut callable) == 0 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
if !callable.is_object() ||
|
||||
JS_ObjectIsCallable(cx, callable.to_object()) == 0 {
|
||||
// FIXME(#347)
|
||||
//ThrowErrorMessage(cx, MSG_NOT_CALLABLE, description.get());
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
Ok(callable)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps the reflector for `p` into the compartment of `cx`.
|
||||
pub fn WrapCallThisObject<T: Reflectable>(cx: *mut JSContext,
|
||||
p: &JSRef<T>) -> *mut JSObject {
|
||||
let mut obj = p.reflector().get_jsobject();
|
||||
assert!(obj.is_not_null());
|
||||
|
||||
unsafe {
|
||||
if JS_WrapObject(cx, &mut obj) == 0 {
|
||||
return ptr::mut_null();
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// A class that performs whatever setup we need to safely make a call while
|
||||
/// this class is on the stack. After `new` returns, the call is safe to make.
|
||||
pub struct CallSetup {
|
||||
/// The `JSContext` used for the call.
|
||||
cx: *mut JSContext,
|
||||
/// The exception handling used for the call.
|
||||
_handling: ExceptionHandling
|
||||
}
|
||||
|
||||
impl CallSetup {
|
||||
/// Performs the setup needed to make a call.
|
||||
pub fn new<T: CallbackContainer>(callback: &T, handling: ExceptionHandling) -> CallSetup {
|
||||
let global = global_object_for_js_object(callback.callback());
|
||||
let global = global.root();
|
||||
let cx = global.root_ref().get_cx();
|
||||
CallSetup {
|
||||
cx: cx,
|
||||
_handling: handling
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `JSContext` used for the call.
|
||||
pub fn GetContext(&self) -> *mut JSContext {
|
||||
self.cx
|
||||
}
|
||||
}
|
52
components/script/dom/bindings/codegen/BindingGen.py
Normal file
52
components/script/dom/bindings/codegen/BindingGen.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
# 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()
|
633
components/script/dom/bindings/codegen/BindingUtils.cpp
Normal file
633
components/script/dom/bindings/codegen/BindingUtils.cpp
Normal file
|
@ -0,0 +1,633 @@
|
|||
/* -*- 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
|
1151
components/script/dom/bindings/codegen/BindingUtils.h
Normal file
1151
components/script/dom/bindings/codegen/BindingUtils.h
Normal file
File diff suppressed because it is too large
Load diff
28
components/script/dom/bindings/codegen/Bindings.conf
Normal file
28
components/script/dom/bindings/codegen/Bindings.conf
Normal file
|
@ -0,0 +1,28 @@
|
|||
# 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': {},
|
||||
|
||||
}
|
5788
components/script/dom/bindings/codegen/Codegen.py
Normal file
5788
components/script/dom/bindings/codegen/Codegen.py
Normal file
File diff suppressed because it is too large
Load diff
5534
components/script/dom/bindings/codegen/CodegenRust.py
Normal file
5534
components/script/dom/bindings/codegen/CodegenRust.py
Normal file
File diff suppressed because it is too large
Load diff
341
components/script/dom/bindings/codegen/Configuration.py
Normal file
341
components/script/dom/bindings/codegen/Configuration.py
Normal file
|
@ -0,0 +1,341 @@
|
|||
# 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
|
114
components/script/dom/bindings/codegen/DOMJSClass.h
Normal file
114
components/script/dom/bindings/codegen/DOMJSClass.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* -*- 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 */
|
247
components/script/dom/bindings/codegen/DOMJSProxyHandler.cpp
Normal file
247
components/script/dom/bindings/codegen/DOMJSProxyHandler.cpp
Normal file
|
@ -0,0 +1,247 @@
|
|||
/* -*- 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
|
109
components/script/dom/bindings/codegen/DOMJSProxyHandler.h
Normal file
109
components/script/dom/bindings/codegen/DOMJSProxyHandler.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* -*- 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 */
|
59
components/script/dom/bindings/codegen/ErrorResult.h
Normal file
59
components/script/dom/bindings/codegen/ErrorResult.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* -*- 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 */
|
30
components/script/dom/bindings/codegen/Errors.msg
Normal file
30
components/script/dom/bindings/codegen/Errors.msg
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* 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}.")
|
|
@ -0,0 +1,26 @@
|
|||
# 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 }))
|
83
components/script/dom/bindings/codegen/GlobalGen.py
Normal file
83
components/script/dom/bindings/codegen/GlobalGen.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
# 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()
|
165
components/script/dom/bindings/codegen/Makefile.in
Normal file
165
components/script/dom/bindings/codegen/Makefile.in
Normal file
|
@ -0,0 +1,165 @@
|
|||
# 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)
|
68
components/script/dom/bindings/codegen/Nullable.h
Normal file
68
components/script/dom/bindings/codegen/Nullable.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* -*- 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 */
|
350
components/script/dom/bindings/codegen/PrimitiveConversions.h
Normal file
350
components/script/dom/bindings/codegen/PrimitiveConversions.h
Normal file
|
@ -0,0 +1,350 @@
|
|||
/* -*- 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 */
|
14
components/script/dom/bindings/codegen/RegisterBindings.h
Normal file
14
components/script/dom/bindings/codegen/RegisterBindings.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#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__
|
121
components/script/dom/bindings/codegen/TypedArray.h
Normal file
121
components/script/dom/bindings/codegen/TypedArray.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/* -*- 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 */
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
window.getComputedStyle(new Worker("404.js"));
|
||||
}
|
||||
|
||||
window.addEventListener("load", boom, false);
|
||||
|
||||
</script>
|
|
@ -0,0 +1 @@
|
|||
asserts-if(cocoaWidget,0-1) load 769464.html
|
1
components/script/dom/bindings/codegen/parser/README
Normal file
1
components/script/dom/bindings/codegen/parser/README
Normal file
|
@ -0,0 +1 @@
|
|||
A WebIDL parser written in Python to be used in Mozilla.
|
1
components/script/dom/bindings/codegen/parser/UPSTREAM
Normal file
1
components/script/dom/bindings/codegen/parser/UPSTREAM
Normal file
|
@ -0,0 +1 @@
|
|||
http://dev.w3.org/cvsweb/~checkout~/2006/webapi/WebIDL/Overview.html?rev=1.409;content-type=text%2Fhtml%3b+charset=utf-8
|
5583
components/script/dom/bindings/codegen/parser/WebIDL.py
Normal file
5583
components/script/dom/bindings/codegen/parser/WebIDL.py
Normal file
File diff suppressed because it is too large
Load diff
49
components/script/dom/bindings/codegen/parser/external.patch
Normal file
49
components/script/dom/bindings/codegen/parser/external.patch
Normal file
|
@ -0,0 +1,49 @@
|
|||
--- 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):
|
12
components/script/dom/bindings/codegen/parser/module.patch
Normal file
12
components/script/dom/bindings/codegen/parser/module.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
--- 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
|
||||
|
79
components/script/dom/bindings/codegen/parser/runtests.py
Normal file
79
components/script/dom/bindings/codegen/parser/runtests.py
Normal file
|
@ -0,0 +1,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/.
|
||||
|
||||
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)
|
|
@ -0,0 +1,14 @@
|
|||
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.")
|
|
@ -0,0 +1,14 @@
|
|||
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.")
|
|
@ -0,0 +1,14 @@
|
|||
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.")
|
|
@ -0,0 +1,13 @@
|
|||
import WebIDL
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
parser.parse("""
|
||||
interface A {
|
||||
attribute long a;
|
||||
};
|
||||
|
||||
interface B {
|
||||
attribute A[] b;
|
||||
};
|
||||
""");
|
||||
parser.finish()
|
|
@ -0,0 +1,84 @@
|
|||
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")
|
302
components/script/dom/bindings/codegen/parser/tests/test_attr.py
Normal file
302
components/script/dom/bindings/codegen/parser/tests/test_attr.py
Normal file
|
@ -0,0 +1,302 @@
|
|||
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")
|
|
@ -0,0 +1,67 @@
|
|||
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")
|
|
@ -0,0 +1,11 @@
|
|||
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')
|
|
@ -0,0 +1,41 @@
|
|||
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")
|
|
@ -0,0 +1,34 @@
|
|||
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")
|
|
@ -0,0 +1,47 @@
|
|||
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")
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
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)
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
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)])])
|
|
@ -0,0 +1,28 @@
|
|||
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.")
|
|
@ -0,0 +1,15 @@
|
|||
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.")
|
|
@ -0,0 +1,198 @@
|
|||
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")
|
|
@ -0,0 +1,150 @@
|
|||
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")
|
|
@ -0,0 +1,14 @@
|
|||
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.")
|
|
@ -0,0 +1,84 @@
|
|||
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.")
|
|
@ -0,0 +1,14 @@
|
|||
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()
|
|
@ -0,0 +1,81 @@
|
|||
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")
|
|
@ -0,0 +1,13 @@
|
|||
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")
|
|
@ -0,0 +1,20 @@
|
|||
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.")
|
|
@ -0,0 +1,28 @@
|
|||
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.")
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
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")
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
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.")
|
|
@ -0,0 +1,216 @@
|
|||
# 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'")
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
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.")
|
|
@ -0,0 +1,44 @@
|
|||
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")
|
|
@ -0,0 +1,188 @@
|
|||
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")
|
|
@ -0,0 +1,15 @@
|
|||
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.")
|
|
@ -0,0 +1,60 @@
|
|||
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.")
|
|
@ -0,0 +1,145 @@
|
|||
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")
|
|
@ -0,0 +1,126 @@
|
|||
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)
|
|
@ -0,0 +1,14 @@
|
|||
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.")
|
|
@ -0,0 +1,14 @@
|
|||
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.")
|
|
@ -0,0 +1,47 @@
|
|||
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")
|
|
@ -0,0 +1,7 @@
|
|||
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.")
|
|
@ -0,0 +1,294 @@
|
|||
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.")
|
|
@ -0,0 +1,73 @@
|
|||
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)
|
|
@ -0,0 +1,62 @@
|
|||
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.")
|
|
@ -0,0 +1,56 @@
|
|||
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.")
|
|
@ -0,0 +1,76 @@
|
|||
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")
|
|
@ -0,0 +1,169 @@
|
|||
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()
|
|
@ -0,0 +1,14 @@
|
|||
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.")
|
|
@ -0,0 +1,53 @@
|
|||
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.")
|
|
@ -0,0 +1,10 @@
|
|||
import WebIDL
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
parser.parse("""
|
||||
callback TestVariadicCallback = any(any... arguments);
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
|
||||
harness.ok(True, "TestVariadicCallback callback parsed without error.")
|
|
@ -0,0 +1,39 @@
|
|||
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.")
|
3
components/script/dom/bindings/codegen/parser/update.sh
Executable file
3
components/script/dom/bindings/codegen/parser/update.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
wget https://mxr.mozilla.org/mozilla-central/source/dom/bindings/parser/WebIDL.py?raw=1 -O WebIDL.py
|
||||
patch < external.patch
|
||||
patch < module.patch
|
28
components/script/dom/bindings/codegen/ply/COPYING
Normal file
28
components/script/dom/bindings/codegen/ply/COPYING
Normal file
|
@ -0,0 +1,28 @@
|
|||
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.
|
9
components/script/dom/bindings/codegen/ply/README
Normal file
9
components/script/dom/bindings/codegen/ply/README
Normal file
|
@ -0,0 +1,9 @@
|
|||
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.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
# PLY package
|
||||
# Author: David Beazley (dave@dabeaz.com)
|
||||
|
||||
__all__ = ['lex','yacc']
|
1058
components/script/dom/bindings/codegen/ply/ply/lex.py
Normal file
1058
components/script/dom/bindings/codegen/ply/ply/lex.py
Normal file
File diff suppressed because it is too large
Load diff
3276
components/script/dom/bindings/codegen/ply/ply/yacc.py
Normal file
3276
components/script/dom/bindings/codegen/ply/ply/yacc.py
Normal file
File diff suppressed because it is too large
Load diff
60
components/script/dom/bindings/codegen/pythonpath.py
Normal file
60
components/script/dom/bindings/codegen/pythonpath.py
Normal file
|
@ -0,0 +1,60 @@
|
|||
# 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:])
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- 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);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/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"
|
||||
|
87
components/script/dom/bindings/codegen/test/Makefile.in
Normal file
87
components/script/dom/bindings/codegen/test/Makefile.in
Normal file
|
@ -0,0 +1,87 @@
|
|||
# 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
|
653
components/script/dom/bindings/codegen/test/TestBindingHeader.h
Normal file
653
components/script/dom/bindings/codegen/test/TestBindingHeader.h
Normal file
|
@ -0,0 +1,653 @@
|
|||
/* -*- 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 */
|
442
components/script/dom/bindings/codegen/test/TestCodeGen.webidl
Normal file
442
components/script/dom/bindings/codegen/test/TestCodeGen.webidl
Normal file
|
@ -0,0 +1,442 @@
|
|||
/* -*- 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;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
/* -*- 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;
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
/* -*- 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;
|
|
@ -0,0 +1,5 @@
|
|||
<body>
|
||||
<script>
|
||||
worker = new Worker("a");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,13 @@
|
|||
<!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>
|
|
@ -0,0 +1,28 @@
|
|||
<!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>
|
|
@ -0,0 +1,11 @@
|
|||
<!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>
|
|
@ -0,0 +1,37 @@
|
|||
<!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>
|
|
@ -0,0 +1,30 @@
|
|||
<!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>
|
15
components/script/dom/bindings/codegen/test/test_enums.html
Normal file
15
components/script/dom/bindings/codegen/test/test_enums.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!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>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue