mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
servo: Merge #17254 - Update the WebIDL parser (from servo:webidl); r=jdm
Source-Repo: https://github.com/servo/servo Source-Revision: 0c929ad3fd902f4314844787868fe891033d3b01 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 39a79ac6b1aefd9222663d328bb2b133f2455b98
This commit is contained in:
parent
3a2e1cf12d
commit
0279918943
@ -17,11 +17,12 @@ import functools
|
||||
from WebIDL import (
|
||||
BuiltinTypes,
|
||||
IDLBuiltinType,
|
||||
IDLNullValue,
|
||||
IDLNullableType,
|
||||
IDLObject,
|
||||
IDLType,
|
||||
IDLInterfaceMember,
|
||||
IDLNullableType,
|
||||
IDLNullValue,
|
||||
IDLObject,
|
||||
IDLPromiseType,
|
||||
IDLType,
|
||||
IDLUndefinedValue,
|
||||
IDLWrapperType,
|
||||
)
|
||||
@ -94,14 +95,14 @@ def stripTrailingWhitespace(text):
|
||||
|
||||
|
||||
def innerContainerType(type):
|
||||
assert type.isSequence() or type.isMozMap()
|
||||
assert type.isSequence() or type.isRecord()
|
||||
return type.inner.inner if type.nullable() else type.inner
|
||||
|
||||
|
||||
def wrapInNativeContainerType(type, inner):
|
||||
if type.isSequence():
|
||||
containerType = "Vec"
|
||||
elif type.isMozMap():
|
||||
elif type.isRecord():
|
||||
containerType = "MozMap"
|
||||
else:
|
||||
raise TypeError("Unexpected container type %s", type)
|
||||
@ -697,7 +698,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
|
||||
assert not (isEnforceRange and isClamp) # These are mutually exclusive
|
||||
|
||||
if type.isSequence() or type.isMozMap():
|
||||
if type.isSequence() or type.isRecord():
|
||||
innerInfo = getJSToNativeConversionInfo(innerContainerType(type),
|
||||
descriptorProvider,
|
||||
isMember=isMember)
|
||||
@ -754,6 +755,56 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
|
||||
return handleOptional(templateBody, declType, default)
|
||||
|
||||
if type.isPromise():
|
||||
assert not type.nullable()
|
||||
# Per spec, what we're supposed to do is take the original
|
||||
# Promise.resolve and call it with the original Promise as this
|
||||
# value to make a Promise out of whatever value we actually have
|
||||
# here. The question is which global we should use. There are
|
||||
# a couple cases to consider:
|
||||
#
|
||||
# 1) Normal call to API with a Promise argument. This is a case the
|
||||
# spec covers, and we should be using the current Realm's
|
||||
# Promise. That means the current compartment.
|
||||
# 2) Promise return value from a callback or callback interface.
|
||||
# This is in theory a case the spec covers but in practice it
|
||||
# really doesn't define behavior here because it doesn't define
|
||||
# what Realm we're in after the callback returns, which is when
|
||||
# the argument conversion happens. We will use the current
|
||||
# compartment, which is the compartment of the callable (which
|
||||
# may itself be a cross-compartment wrapper itself), which makes
|
||||
# as much sense as anything else. In practice, such an API would
|
||||
# once again be providing a Promise to signal completion of an
|
||||
# operation, which would then not be exposed to anyone other than
|
||||
# our own implementation code.
|
||||
templateBody = fill(
|
||||
"""
|
||||
{ // Scope for our JSAutoCompartment.
|
||||
|
||||
rooted!(in(cx) let globalObj = CurrentGlobalOrNull(cx));
|
||||
let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get());
|
||||
|
||||
rooted!(in(cx) let mut valueToResolve = $${val}.get());
|
||||
if !JS_WrapValue(cx, valueToResolve.handle_mut()) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
match Promise::Resolve(&promiseGlobal, cx, valueToResolve.handle()) {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
throw_dom_exception(cx, &promiseGlobal, error);
|
||||
$*{exceptionCode}
|
||||
}
|
||||
}
|
||||
}
|
||||
""",
|
||||
exceptionCode=exceptionCode)
|
||||
|
||||
if isArgument:
|
||||
declType = CGGeneric("&Promise")
|
||||
else:
|
||||
declType = CGGeneric("Rc<Promise>")
|
||||
return handleOptional(templateBody, declType, handleDefaultNull("None"))
|
||||
|
||||
if type.isGeckoInterface():
|
||||
assert not isEnforceRange and not isClamp
|
||||
|
||||
@ -780,79 +831,34 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
elif isArgument:
|
||||
descriptorType = descriptor.argumentType
|
||||
|
||||
templateBody = ""
|
||||
isPromise = descriptor.interface.identifier.name == "Promise"
|
||||
if isPromise:
|
||||
# Per spec, what we're supposed to do is take the original
|
||||
# Promise.resolve and call it with the original Promise as this
|
||||
# value to make a Promise out of whatever value we actually have
|
||||
# here. The question is which global we should use. There are
|
||||
# a couple cases to consider:
|
||||
#
|
||||
# 1) Normal call to API with a Promise argument. This is a case the
|
||||
# spec covers, and we should be using the current Realm's
|
||||
# Promise. That means the current compartment.
|
||||
# 2) Promise return value from a callback or callback interface.
|
||||
# This is in theory a case the spec covers but in practice it
|
||||
# really doesn't define behavior here because it doesn't define
|
||||
# what Realm we're in after the callback returns, which is when
|
||||
# the argument conversion happens. We will use the current
|
||||
# compartment, which is the compartment of the callable (which
|
||||
# may itself be a cross-compartment wrapper itself), which makes
|
||||
# as much sense as anything else. In practice, such an API would
|
||||
# once again be providing a Promise to signal completion of an
|
||||
# operation, which would then not be exposed to anyone other than
|
||||
# our own implementation code.
|
||||
templateBody = fill(
|
||||
"""
|
||||
{ // Scope for our JSAutoCompartment.
|
||||
if descriptor.interface.isConsequential():
|
||||
raise TypeError("Consequential interface %s being used as an "
|
||||
"argument" % descriptor.interface.identifier.name)
|
||||
|
||||
rooted!(in(cx) let globalObj = CurrentGlobalOrNull(cx));
|
||||
let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get());
|
||||
|
||||
rooted!(in(cx) let mut valueToResolve = $${val}.get());
|
||||
if !JS_WrapValue(cx, valueToResolve.handle_mut()) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
match Promise::Resolve(&promiseGlobal, cx, valueToResolve.handle()) {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
throw_dom_exception(cx, &promiseGlobal, error);
|
||||
$*{exceptionCode}
|
||||
}
|
||||
}
|
||||
}
|
||||
""",
|
||||
exceptionCode=exceptionCode)
|
||||
if failureCode is None:
|
||||
substitutions = {
|
||||
"sourceDescription": sourceDescription,
|
||||
"interface": descriptor.interface.identifier.name,
|
||||
"exceptionCode": exceptionCode,
|
||||
}
|
||||
unwrapFailureCode = string.Template(
|
||||
'throw_type_error(cx, "${sourceDescription} does not '
|
||||
'implement interface ${interface}.");\n'
|
||||
'${exceptionCode}').substitute(substitutions)
|
||||
else:
|
||||
if descriptor.interface.isConsequential():
|
||||
raise TypeError("Consequential interface %s being used as an "
|
||||
"argument" % descriptor.interface.identifier.name)
|
||||
unwrapFailureCode = failureCode
|
||||
|
||||
if failureCode is None:
|
||||
substitutions = {
|
||||
"sourceDescription": sourceDescription,
|
||||
"interface": descriptor.interface.identifier.name,
|
||||
"exceptionCode": exceptionCode,
|
||||
templateBody = fill(
|
||||
"""
|
||||
match ${function}($${val}) {
|
||||
Ok(val) => val,
|
||||
Err(()) => {
|
||||
$*{failureCode}
|
||||
}
|
||||
unwrapFailureCode = string.Template(
|
||||
'throw_type_error(cx, "${sourceDescription} does not '
|
||||
'implement interface ${interface}.");\n'
|
||||
'${exceptionCode}').substitute(substitutions)
|
||||
else:
|
||||
unwrapFailureCode = failureCode
|
||||
|
||||
templateBody = fill(
|
||||
"""
|
||||
match ${function}($${val}) {
|
||||
Ok(val) => val,
|
||||
Err(()) => {
|
||||
$*{failureCode}
|
||||
}
|
||||
}
|
||||
""",
|
||||
failureCode=unwrapFailureCode + "\n",
|
||||
function=conversionFunction)
|
||||
}
|
||||
""",
|
||||
failureCode=unwrapFailureCode + "\n",
|
||||
function=conversionFunction)
|
||||
|
||||
declType = CGGeneric(descriptorType)
|
||||
if type.nullable():
|
||||
@ -1323,7 +1329,7 @@ def typeNeedsCx(type, retVal=False):
|
||||
|
||||
# Returns a conversion behavior suitable for a type
|
||||
def getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs):
|
||||
if type.isSequence() or type.isMozMap():
|
||||
if type.isSequence() or type.isRecord():
|
||||
return getConversionConfigForType(innerContainerType(type), isEnforceRange, isClamp, treatNullAs)
|
||||
if type.isDOMString():
|
||||
assert not isEnforceRange and not isClamp
|
||||
@ -1381,6 +1387,9 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
|
||||
if returnType.nullable():
|
||||
result = CGWrapper(result, pre="Option<", post=">")
|
||||
return result
|
||||
if returnType.isPromise():
|
||||
assert not returnType.nullable()
|
||||
return CGGeneric("Rc<Promise>")
|
||||
if returnType.isGeckoInterface():
|
||||
descriptor = descriptorProvider.getDescriptor(
|
||||
returnType.unroll().inner.identifier.name)
|
||||
@ -1408,7 +1417,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
|
||||
if returnType.nullable():
|
||||
result = CGWrapper(result, pre="Option<", post=">")
|
||||
return result
|
||||
if returnType.isSequence() or returnType.isMozMap():
|
||||
if returnType.isSequence() or returnType.isRecord():
|
||||
result = getRetvalDeclarationForType(innerContainerType(returnType), descriptorProvider)
|
||||
result = wrapInNativeContainerType(returnType, result)
|
||||
if returnType.nullable():
|
||||
@ -1946,8 +1955,10 @@ class CGImports(CGWrapper):
|
||||
if parentName:
|
||||
descriptor = descriptorProvider.getDescriptor(parentName)
|
||||
extras += [descriptor.path, descriptor.bindingPath]
|
||||
elif t.isType() and t.isMozMap():
|
||||
elif t.isType() and t.isRecord():
|
||||
extras += ['dom::bindings::mozmap::MozMap']
|
||||
elif isinstance(t, IDLPromiseType):
|
||||
extras += ["dom::promise::Promise"]
|
||||
else:
|
||||
if t.isEnum():
|
||||
extras += [getModuleFromObject(t) + '::' + getIdentifier(t).name + 'Values']
|
||||
@ -3819,7 +3830,9 @@ class CGMemberJITInfo(CGThing):
|
||||
return "JSVAL_TYPE_UNDEFINED"
|
||||
if t.isSequence():
|
||||
return "JSVAL_TYPE_OBJECT"
|
||||
if t.isMozMap():
|
||||
if t.isRecord():
|
||||
return "JSVAL_TYPE_OBJECT"
|
||||
if t.isPromise():
|
||||
return "JSVAL_TYPE_OBJECT"
|
||||
if t.isGeckoInterface():
|
||||
return "JSVAL_TYPE_OBJECT"
|
||||
@ -4055,7 +4068,7 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
|
||||
elif type.isDictionary():
|
||||
name = type.name
|
||||
typeName = name
|
||||
elif type.isSequence() or type.isMozMap():
|
||||
elif type.isSequence() or type.isRecord():
|
||||
name = type.name
|
||||
inner = getUnionTypeTemplateVars(innerContainerType(type), descriptorProvider)
|
||||
typeName = wrapInNativeContainerType(type, CGGeneric(inner["typeName"])).define()
|
||||
@ -4208,7 +4221,7 @@ class CGUnionConversionStruct(CGThing):
|
||||
else:
|
||||
object = None
|
||||
|
||||
mozMapMemberTypes = filter(lambda t: t.isMozMap(), memberTypes)
|
||||
mozMapMemberTypes = filter(lambda t: t.isRecord(), memberTypes)
|
||||
if len(mozMapMemberTypes) > 0:
|
||||
assert len(mozMapMemberTypes) == 1
|
||||
typeName = mozMapMemberTypes[0].name
|
||||
@ -6870,6 +6883,8 @@ def process_arg(expr, arg):
|
||||
expr += ".r()"
|
||||
else:
|
||||
expr = "&" + expr
|
||||
elif isinstance(arg.type, IDLPromiseType):
|
||||
expr = "&" + expr
|
||||
return expr
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,162 @@
|
||||
def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions(DOMString a)] void foo(boolean arg2);
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] with an argument")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions(DOMString b)] readonly attribute boolean bar;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] with an argument")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] attribute boolean bar;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except Exception, e:
|
||||
harness.ok(False, "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" % e)
|
||||
threw = True
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] void foo(boolean arg2);
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except Exception, e:
|
||||
harness.ok(False, "Shouldn't have thrown for [CEReactions] used on regular operations. %s" % e)
|
||||
threw = True
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] readonly attribute boolean A;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] used on a readonly attribute")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[CEReactions]
|
||||
interface Foo {
|
||||
}
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] used on a interface")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] getter any(DOMString name);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown for [CEReactions] used on a named getter")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] creator boolean (DOMString name, boolean value);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown for [CEReactions] used on a named creator")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] legacycaller double compute(double x);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown for [CEReactions] used on a legacycaller")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] stringifier DOMString ();
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown for [CEReactions] used on a stringifier")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Foo {
|
||||
[CEReactions] jsonifier;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for [CEReactions] used on a jsonifier")
|
@ -13,7 +13,7 @@ def WebIDLTest(parser, harness):
|
||||
def checkMethod(method, QName, name, signatures,
|
||||
static=True, getter=False, setter=False, creator=False,
|
||||
deleter=False, legacycaller=False, stringifier=False,
|
||||
chromeOnly=False):
|
||||
chromeOnly=False, htmlConstructor=False):
|
||||
harness.ok(isinstance(method, WebIDL.IDLMethod),
|
||||
"Should be an IDLMethod")
|
||||
harness.ok(method.isMethod(), "Method is a method")
|
||||
@ -29,6 +29,7 @@ def WebIDLTest(parser, harness):
|
||||
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
|
||||
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
|
||||
harness.check(method.getExtendedAttribute("ChromeOnly") is not None, chromeOnly, "Method has the correct value for ChromeOnly")
|
||||
harness.check(method.isHTMLConstructor(), htmlConstructor, "Method has the correct htmlConstructor value")
|
||||
harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
|
||||
|
||||
sigpairs = zip(method.signatures(), signatures)
|
||||
@ -93,6 +94,21 @@ def WebIDLTest(parser, harness):
|
||||
"constructor", [("TestChromeConstructor (Wrapper)", [])],
|
||||
chromeOnly=True)
|
||||
|
||||
parser = parser.reset()
|
||||
parser.parse("""
|
||||
[HTMLConstructor]
|
||||
interface TestHTMLConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.check(len(results), 1, "Should be one production")
|
||||
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
|
||||
checkMethod(results[0].ctor(), "::TestHTMLConstructor::constructor",
|
||||
"constructor", [("TestHTMLConstructor (Wrapper)", [])],
|
||||
htmlConstructor=True)
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
@ -107,3 +123,151 @@ def WebIDLTest(parser, harness):
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a Constructor and a ChromeConstructor")
|
||||
|
||||
# Test HTMLConstructor with argument
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor(DOMString a)]
|
||||
interface TestHTMLConstructorWithArgs {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "HTMLConstructor should take no argument")
|
||||
|
||||
# Test HTMLConstructor on a callback interface
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor]
|
||||
callback interface TestHTMLConstructorOnCallbackInterface {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "HTMLConstructor can't be used on a callback interface")
|
||||
|
||||
# Test HTMLConstructor and Constructor
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[Constructor,
|
||||
HTMLConstructor]
|
||||
interface TestHTMLConstructorAndConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a Constructor and a HTMLConstructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor,
|
||||
Constructor]
|
||||
interface TestHTMLConstructorAndConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor,
|
||||
Constructor(DOMString a)]
|
||||
interface TestHTMLConstructorAndConstructor {
|
||||
};
|
||||
""")
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[Constructor(DOMString a),
|
||||
HTMLConstructor]
|
||||
interface TestHTMLConstructorAndConstructor {
|
||||
};
|
||||
""")
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor")
|
||||
|
||||
# Test HTMLConstructor and ChromeConstructor
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[ChromeConstructor,
|
||||
HTMLConstructor]
|
||||
interface TestHTMLConstructorAndChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor,
|
||||
ChromeConstructor]
|
||||
interface TestHTMLConstructorAndChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[ChromeConstructor(DOMString a),
|
||||
HTMLConstructor]
|
||||
interface TestHTMLConstructorAndChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor,
|
||||
ChromeConstructor(DOMString a)]
|
||||
interface TestHTMLConstructorAndChromeConstructor {
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor")
|
||||
|
@ -34,3 +34,36 @@ def WebIDLTest(parser, harness):
|
||||
interface TestNamedConstructorNoInterfaceObject {
|
||||
};
|
||||
""")
|
||||
|
||||
# Test HTMLConstructor and NoInterfaceObject
|
||||
parser = parser.reset()
|
||||
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[NoInterfaceObject, HTMLConstructor]
|
||||
interface TestHTMLConstructorNoInterfaceObject {
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
|
||||
parser = parser.reset()
|
||||
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
[HTMLConstructor, NoInterfaceObject]
|
||||
interface TestHTMLConstructorNoInterfaceObject {
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
|
@ -158,21 +158,27 @@ def WebIDLTest(parser, harness):
|
||||
"CallbackInterface?", "CallbackInterface2",
|
||||
"object", "Callback", "Callback2", "optional Dict",
|
||||
"optional Dict2", "sequence<long>", "sequence<short>",
|
||||
"MozMap<object>", "MozMap<Dict>", "MozMap<long>",
|
||||
"record<DOMString, object>",
|
||||
"record<USVString, Dict>",
|
||||
"record<ByteString, long>",
|
||||
"Date", "Date?", "any",
|
||||
"Promise<any>", "Promise<any>?",
|
||||
"USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
|
||||
"Uint8Array", "Uint16Array" ]
|
||||
# When we can parse Date and RegExp, we need to add them here.
|
||||
"Uint8Array", "Uint16Array",
|
||||
"(long or Callback)", "optional (long or Dict)",
|
||||
]
|
||||
# When we can parse Date, we need to add it here.
|
||||
# XXXbz we can, and should really do that...
|
||||
|
||||
# Try to categorize things a bit to keep list lengths down
|
||||
def allBut(list1, list2):
|
||||
return [a for a in list1 if a not in list2 and
|
||||
(a != "any" and a != "Promise<any>" and a != "Promise<any>?")]
|
||||
unions = [ "(long or Callback)", "optional (long or Dict)" ]
|
||||
numerics = [ "long", "short", "long?", "short?" ]
|
||||
booleans = [ "boolean", "boolean?" ]
|
||||
primitives = numerics + booleans
|
||||
nonNumerics = allBut(argTypes, numerics)
|
||||
nonNumerics = allBut(argTypes, numerics + unions)
|
||||
nonBooleans = allBut(argTypes, booleans)
|
||||
strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString" ]
|
||||
nonStrings = allBut(argTypes, strings)
|
||||
@ -182,16 +188,18 @@ def WebIDLTest(parser, harness):
|
||||
sharedBufferSourceTypes = ["SharedArrayBuffer"]
|
||||
interfaces = [ "Interface", "Interface?", "AncestorInterface",
|
||||
"UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
|
||||
nullables = ["long?", "short?", "boolean?", "Interface?",
|
||||
"CallbackInterface?", "optional Dict", "optional Dict2",
|
||||
"Date?", "any", "Promise<any>?"]
|
||||
nullables = (["long?", "short?", "boolean?", "Interface?",
|
||||
"CallbackInterface?", "optional Dict", "optional Dict2",
|
||||
"Date?", "any", "Promise<any>?"] +
|
||||
allBut(unions, [ "(long or Callback)" ]))
|
||||
dates = [ "Date", "Date?" ]
|
||||
sequences = [ "sequence<long>", "sequence<short>" ]
|
||||
nonUserObjects = nonObjects + interfaces + dates + sequences
|
||||
otherObjects = allBut(argTypes, nonUserObjects + ["object"])
|
||||
notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
|
||||
otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
|
||||
mozMaps = [ "MozMap<object>", "MozMap<Dict>", "MozMap<long>" ]
|
||||
records = [ "record<DOMString, object>", "record<USVString, Dict>",
|
||||
"record<ByteString, long>" ]
|
||||
|
||||
# Build a representation of the distinguishability table as a dict
|
||||
# of dicts, holding True values where needed, holes elsewhere.
|
||||
@ -231,9 +239,9 @@ def WebIDLTest(parser, harness):
|
||||
allBut(argTypes, sequences + ["object"]))
|
||||
setDistinguishable("sequence<short>",
|
||||
allBut(argTypes, sequences + ["object"]))
|
||||
setDistinguishable("MozMap<object>", nonUserObjects)
|
||||
setDistinguishable("MozMap<Dict>", nonUserObjects)
|
||||
setDistinguishable("MozMap<long>", nonUserObjects)
|
||||
setDistinguishable("record<DOMString, object>", nonUserObjects)
|
||||
setDistinguishable("record<USVString, Dict>", nonUserObjects)
|
||||
setDistinguishable("record<ByteString, long>", nonUserObjects)
|
||||
setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
|
||||
setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
|
||||
setDistinguishable("any", [])
|
||||
@ -244,6 +252,10 @@ def WebIDLTest(parser, harness):
|
||||
setDistinguishable("Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]))
|
||||
setDistinguishable("Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]))
|
||||
setDistinguishable("SharedArrayBuffer", allBut(argTypes, ["SharedArrayBuffer", "object"]))
|
||||
setDistinguishable("(long or Callback)",
|
||||
allBut(nonUserObjects, numerics))
|
||||
setDistinguishable("optional (long or Dict)",
|
||||
allBut(nonUserObjects, numerics + nullables))
|
||||
|
||||
def areDistinguishable(type1, type2):
|
||||
return data[type1].get(type2, False)
|
||||
@ -263,7 +275,6 @@ def WebIDLTest(parser, harness):
|
||||
callback Callback2 = long(short arg);
|
||||
dictionary Dict {};
|
||||
dictionary Dict2 {};
|
||||
interface _Promise {};
|
||||
interface TestInterface {%s
|
||||
};
|
||||
"""
|
||||
|
@ -0,0 +1,39 @@
|
||||
# Import the WebIDL module, so we can do isinstance checks and whatnot
|
||||
import WebIDL
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
try:
|
||||
parser.parse("""
|
||||
enum Foo { "a" };
|
||||
interface Foo;
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.ok(False, "Should fail to parse")
|
||||
except Exception, e:
|
||||
harness.ok("Name collision" in e.message,
|
||||
"Should have name collision for interface")
|
||||
|
||||
parser = parser.reset()
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo { long x; };
|
||||
enum Foo { "a" };
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.ok(False, "Should fail to parse")
|
||||
except Exception, e:
|
||||
harness.ok("Name collision" in e.message,
|
||||
"Should have name collision for dictionary")
|
||||
|
||||
parser = parser.reset()
|
||||
try:
|
||||
parser.parse("""
|
||||
enum Foo { "a" };
|
||||
enum Foo { "b" };
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.ok(False, "Should fail to parse")
|
||||
except Exception, e:
|
||||
harness.ok("Multiple unresolvable definitions" in e.message,
|
||||
"Should have name collision for dictionary")
|
||||
|
@ -88,6 +88,8 @@ def WebIDLTest(parser, harness):
|
||||
disallowedNonMethodNames = ["clear", "delete"]
|
||||
mapDisallowedNonMethodNames = ["set"] + disallowedNonMethodNames
|
||||
setDisallowedNonMethodNames = ["add"] + disallowedNonMethodNames
|
||||
unrelatedMembers = [("unrelatedAttribute", WebIDL.IDLAttribute),
|
||||
("unrelatedMethod", WebIDL.IDLMethod)]
|
||||
|
||||
#
|
||||
# Simple Usage Tests
|
||||
@ -99,52 +101,147 @@ def WebIDLTest(parser, harness):
|
||||
iterable<long>;
|
||||
readonly attribute unsigned long length;
|
||||
getter long(unsigned long index);
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", valueIterableMembers)
|
||||
""", valueIterableMembers + unrelatedMembers)
|
||||
|
||||
shouldPass("Iterable (key only) inheriting from parent",
|
||||
"""
|
||||
interface Foo1 : Foo2 {
|
||||
iterable<long>;
|
||||
readonly attribute unsigned long length;
|
||||
getter long(unsigned long index);
|
||||
};
|
||||
interface Foo2 {
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", valueIterableMembers, numProductions=2)
|
||||
|
||||
shouldPass("Iterable (key and value)",
|
||||
"""
|
||||
interface Foo1 {
|
||||
iterable<long, long>;
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", iterableMembers,
|
||||
""", iterableMembers + unrelatedMembers,
|
||||
# numProductions == 2 because of the generated iterator iface,
|
||||
numProductions=2)
|
||||
|
||||
shouldPass("Maplike (readwrite)",
|
||||
shouldPass("Iterable (key and value) inheriting from parent",
|
||||
"""
|
||||
interface Foo1 {
|
||||
maplike<long, long>;
|
||||
interface Foo1 : Foo2 {
|
||||
iterable<long, long>;
|
||||
};
|
||||
""", mapRWMembers)
|
||||
interface Foo2 {
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", iterableMembers,
|
||||
# numProductions == 3 because of the generated iterator iface,
|
||||
numProductions=3)
|
||||
|
||||
shouldPass("Maplike (readwrite)",
|
||||
"""
|
||||
interface Foo1 {
|
||||
maplike<long, long>;
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", mapRWMembers)
|
||||
""", mapRWMembers + unrelatedMembers)
|
||||
|
||||
shouldPass("Maplike (readwrite) inheriting from parent",
|
||||
"""
|
||||
interface Foo1 : Foo2 {
|
||||
maplike<long, long>;
|
||||
};
|
||||
interface Foo2 {
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", mapRWMembers, numProductions=2)
|
||||
|
||||
shouldPass("Maplike (readwrite)",
|
||||
"""
|
||||
interface Foo1 {
|
||||
maplike<long, long>;
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", mapRWMembers + unrelatedMembers)
|
||||
|
||||
shouldPass("Maplike (readwrite) inheriting from parent",
|
||||
"""
|
||||
interface Foo1 : Foo2 {
|
||||
maplike<long, long>;
|
||||
};
|
||||
interface Foo2 {
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", mapRWMembers, numProductions=2)
|
||||
|
||||
shouldPass("Maplike (readonly)",
|
||||
"""
|
||||
interface Foo1 {
|
||||
readonly maplike<long, long>;
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", mapROMembers)
|
||||
""", mapROMembers + unrelatedMembers)
|
||||
|
||||
shouldPass("Maplike (readonly) inheriting from parent",
|
||||
"""
|
||||
interface Foo1 : Foo2 {
|
||||
readonly maplike<long, long>;
|
||||
};
|
||||
interface Foo2 {
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", mapROMembers, numProductions=2)
|
||||
|
||||
shouldPass("Setlike (readwrite)",
|
||||
"""
|
||||
interface Foo1 {
|
||||
setlike<long>;
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", setRWMembers)
|
||||
""", setRWMembers + unrelatedMembers)
|
||||
|
||||
shouldPass("Setlike (readwrite) inheriting from parent",
|
||||
"""
|
||||
interface Foo1 : Foo2 {
|
||||
setlike<long>;
|
||||
};
|
||||
interface Foo2 {
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", setRWMembers, numProductions=2)
|
||||
|
||||
shouldPass("Setlike (readonly)",
|
||||
"""
|
||||
interface Foo1 {
|
||||
readonly setlike<long>;
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", setROMembers)
|
||||
""", setROMembers + unrelatedMembers)
|
||||
|
||||
shouldPass("Setlike (readonly) inheriting from parent",
|
||||
"""
|
||||
interface Foo1 : Foo2 {
|
||||
readonly setlike<long>;
|
||||
};
|
||||
interface Foo2 {
|
||||
attribute long unrelatedAttribute;
|
||||
long unrelatedMethod();
|
||||
};
|
||||
""", setROMembers, numProductions=2)
|
||||
|
||||
shouldPass("Inheritance of maplike/setlike",
|
||||
"""
|
||||
|
@ -0,0 +1,70 @@
|
||||
# Import the WebIDL module, so we can do isinstance checks and whatnot
|
||||
import WebIDL
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
# Basic functionality
|
||||
parser.parse(
|
||||
"""
|
||||
interface Iface {
|
||||
[NewObject] readonly attribute Iface attr;
|
||||
[NewObject] Iface method();
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.ok(results, "Should not have thrown on basic [NewObject] usage")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse(
|
||||
"""
|
||||
interface Iface {
|
||||
[Pure, NewObject] readonly attribute Iface attr;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw, "[NewObject] attributes must depend on something")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse(
|
||||
"""
|
||||
interface Iface {
|
||||
[Pure, NewObject] Iface method();
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw, "[NewObject] methods must depend on something")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse(
|
||||
"""
|
||||
interface Iface {
|
||||
[Cached, NewObject, Affects=Nothing] readonly attribute Iface attr;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw, "[NewObject] attributes must not be [Cached]")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse(
|
||||
"""
|
||||
interface Iface {
|
||||
[StoreInSlot, NewObject, Affects=Nothing] readonly attribute Iface attr;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw, "[NewObject] attributes must not be [StoreInSlot]")
|
@ -2,7 +2,6 @@ def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface _Promise {};
|
||||
interface A {
|
||||
legacycaller Promise<any> foo();
|
||||
};
|
||||
@ -18,7 +17,6 @@ def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface _Promise {};
|
||||
interface A {
|
||||
Promise<any> foo();
|
||||
long foo(long arg);
|
||||
@ -35,7 +33,6 @@ def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface _Promise {};
|
||||
interface A {
|
||||
long foo(long arg);
|
||||
Promise<any> foo();
|
||||
@ -48,9 +45,36 @@ def WebIDLTest(parser, harness):
|
||||
"Should not allow overloads which have both Promise and "
|
||||
"non-Promise return types.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
Promise<any>? foo();
|
||||
};
|
||||
""")
|
||||
results = parser.finish();
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should not allow nullable Promise return values.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
void foo(Promise<any>? arg);
|
||||
};
|
||||
""")
|
||||
results = parser.finish();
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should not allow nullable Promise arguments.")
|
||||
|
||||
parser = parser.reset()
|
||||
parser.parse("""
|
||||
interface _Promise {};
|
||||
interface A {
|
||||
Promise<any> foo();
|
||||
Promise<any> foo(long arg);
|
||||
@ -61,3 +85,73 @@ def WebIDLTest(parser, harness):
|
||||
harness.ok(True,
|
||||
"Should allow overloads which only have Promise and return "
|
||||
"types.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
attribute Promise<any> attr;
|
||||
};
|
||||
""")
|
||||
results = parser.finish();
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should not allow writable Promise-typed attributes.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
[LenientSetter] readonly attribute Promise<any> attr;
|
||||
};
|
||||
""")
|
||||
results = parser.finish();
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should not allow [LenientSetter] Promise-typed attributes.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
[PutForwards=bar] readonly attribute Promise<any> attr;
|
||||
};
|
||||
""")
|
||||
results = parser.finish();
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should not allow [PutForwards] Promise-typed attributes.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
[Replaceable] readonly attribute Promise<any> attr;
|
||||
};
|
||||
""")
|
||||
results = parser.finish();
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should not allow [Replaceable] Promise-typed attributes.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
[SameObject] readonly attribute Promise<any> attr;
|
||||
};
|
||||
""")
|
||||
results = parser.finish();
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should not allow [SameObject] Promise-typed attributes.")
|
||||
|
@ -3,8 +3,8 @@ import WebIDL
|
||||
def WebIDLTest(parser, harness):
|
||||
parser.parse("""
|
||||
dictionary Dict {};
|
||||
interface MozMapArg {
|
||||
void foo(MozMap<Dict> arg);
|
||||
interface RecordArg {
|
||||
void foo(record<DOMString, Dict> arg);
|
||||
};
|
||||
""")
|
||||
|
||||
@ -19,7 +19,7 @@ def WebIDLTest(parser, harness):
|
||||
signature = members[0].signatures()[0]
|
||||
args = signature[1]
|
||||
harness.check(len(args), 1, "Should have one arg")
|
||||
harness.ok(args[0].type.isMozMap(), "Should have a MozMap type here")
|
||||
harness.ok(args[0].type.isRecord(), "Should have a record type here")
|
||||
harness.ok(args[0].type.inner.isDictionary(),
|
||||
"Should have a dictionary inner type")
|
||||
|
||||
@ -27,13 +27,27 @@ def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface MozMapVoidArg {
|
||||
void foo(MozMap<void> arg);
|
||||
interface RecordVoidArg {
|
||||
void foo(record<DOMString, void> arg);
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except Exception,x:
|
||||
threw = True
|
||||
harness.ok(threw, "Should have thrown because record can't have void as value type.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Dict {
|
||||
record<DOMString, Dict> val;
|
||||
};
|
||||
""")
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
results = parser.finish()
|
||||
except Exception,x:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should have thrown on dictionary containing itself via record.")
|
@ -6,15 +6,14 @@ def WebIDLTest(parser, harness):
|
||||
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);
|
||||
readonly attribute unsigned long length;
|
||||
};
|
||||
|
||||
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);
|
||||
@ -49,25 +48,39 @@ def WebIDLTest(parser, harness):
|
||||
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",
|
||||
checkMethod(iface.members[3], "::SpecialMethods::__namedgetter", "__namedgetter",
|
||||
getter=True)
|
||||
checkMethod(iface.members[5], "::SpecialMethods::__namedsetter", "__namedsetter",
|
||||
checkMethod(iface.members[4], "::SpecialMethods::__namedsetter", "__namedsetter",
|
||||
setter=True)
|
||||
checkMethod(iface.members[6], "::SpecialMethods::__namedcreator", "__namedcreator",
|
||||
checkMethod(iface.members[5], "::SpecialMethods::__namedcreator", "__namedcreator",
|
||||
creator=True)
|
||||
checkMethod(iface.members[7], "::SpecialMethods::__nameddeleter", "__nameddeleter",
|
||||
checkMethod(iface.members[6], "::SpecialMethods::__nameddeleter", "__nameddeleter",
|
||||
deleter=True)
|
||||
|
||||
iface = results[1]
|
||||
harness.check(len(iface.members), 4, "Expect 4 members")
|
||||
harness.check(len(iface.members), 3, "Expect 3 members")
|
||||
|
||||
checkMethod(iface.members[0], "::SpecialMethodsCombination::__indexedgetterdeleter",
|
||||
"__indexedgetterdeleter", getter=True, deleter=True)
|
||||
checkMethod(iface.members[1], "::SpecialMethodsCombination::__indexedsettercreator",
|
||||
checkMethod(iface.members[0], "::SpecialMethodsCombination::__indexedsettercreator",
|
||||
"__indexedsettercreator", setter=True, creator=True)
|
||||
checkMethod(iface.members[2], "::SpecialMethodsCombination::__namedgetterdeleter",
|
||||
checkMethod(iface.members[1], "::SpecialMethodsCombination::__namedgetterdeleter",
|
||||
"__namedgetterdeleter", getter=True, deleter=True)
|
||||
checkMethod(iface.members[3], "::SpecialMethodsCombination::__namedsettercreator",
|
||||
checkMethod(iface.members[2], "::SpecialMethodsCombination::__namedsettercreator",
|
||||
"__namedsettercreator", setter=True, creator=True)
|
||||
|
||||
parser = parser.reset();
|
||||
|
||||
threw = False
|
||||
try:
|
||||
parser.parse(
|
||||
"""
|
||||
interface IndexedDeleter {
|
||||
deleter void(unsigned long index);
|
||||
};
|
||||
""")
|
||||
parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "There are no indexed deleters")
|
||||
|
||||
|
||||
|
@ -194,7 +194,7 @@ impl Headers {
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
Some(HeadersInit::ByteStringMozMap(m)) => {
|
||||
Some(HeadersInit::StringByteStringRecord(m)) => {
|
||||
for (key, value) in m.iter() {
|
||||
let key_vec = key.as_ref().to_string().into();
|
||||
let headers_key = ByteString::new(key_vec);
|
||||
|
@ -311,9 +311,9 @@ impl Request {
|
||||
try!(headers_copy.fill(Some(
|
||||
HeadersInit::ByteStringSequenceSequence(init_sequence.clone()))));
|
||||
},
|
||||
&HeadersInit::ByteStringMozMap(ref init_map) => {
|
||||
&HeadersInit::StringByteStringRecord(ref init_map) => {
|
||||
try!(headers_copy.fill(Some(
|
||||
HeadersInit::ByteStringMozMap(init_map.clone()))));
|
||||
HeadersInit::StringByteStringRecord(init_map.clone()))));
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -880,8 +880,8 @@ impl Clone for HeadersInit {
|
||||
HeadersInit::Headers(h.clone()),
|
||||
&HeadersInit::ByteStringSequenceSequence(ref b) =>
|
||||
HeadersInit::ByteStringSequenceSequence(b.clone()),
|
||||
&HeadersInit::ByteStringMozMap(ref m) =>
|
||||
HeadersInit::ByteStringMozMap(m.clone()),
|
||||
&HeadersInit::StringByteStringRecord(ref m) =>
|
||||
HeadersInit::StringByteStringRecord(m.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -662,9 +662,9 @@ impl TestBindingMethods for TestBinding {
|
||||
fn PassStringMozMap(&self, _: MozMap<DOMString>) {}
|
||||
fn PassByteStringMozMap(&self, _: MozMap<ByteString>) {}
|
||||
fn PassMozMapOfMozMaps(&self, _: MozMap<MozMap<i32>>) {}
|
||||
fn PassMozMapUnion(&self, _: UnionTypes::LongOrByteStringMozMap) {}
|
||||
fn PassMozMapUnion2(&self, _: UnionTypes::TestBindingOrByteStringMozMap) {}
|
||||
fn PassMozMapUnion3(&self, _: UnionTypes::TestBindingOrByteStringSequenceSequenceOrByteStringMozMap) {}
|
||||
fn PassMozMapUnion(&self, _: UnionTypes::LongOrStringByteStringRecord) {}
|
||||
fn PassMozMapUnion2(&self, _: UnionTypes::TestBindingOrStringByteStringRecord) {}
|
||||
fn PassMozMapUnion3(&self, _: UnionTypes::TestBindingOrByteStringSequenceSequenceOrStringByteStringRecord) {}
|
||||
fn ReceiveMozMap(&self) -> MozMap<i32> { MozMap::new() }
|
||||
fn ReceiveNullableMozMap(&self) -> Option<MozMap<i32>> { Some(MozMap::new()) }
|
||||
fn ReceiveMozMapOfNullableInts(&self) -> MozMap<Option<i32>> { MozMap::new() }
|
||||
@ -750,9 +750,6 @@ impl TestBindingMethods for TestBinding {
|
||||
fn AcceptPromise(&self, _promise: &Promise) {
|
||||
}
|
||||
|
||||
fn AcceptNullablePromise(&self, _promise: Option<&Promise>) {
|
||||
}
|
||||
|
||||
fn PassSequenceSequence(&self, _seq: Vec<Vec<i32>>) {}
|
||||
fn ReturnSequenceSequence(&self) -> Vec<Vec<i32>> { vec![] }
|
||||
fn PassUnionSequenceSequence(&self, seq: LongOrLongSequenceSequence) {
|
||||
|
@ -16,9 +16,9 @@ dictionary BluetoothLEScanFilterInit {
|
||||
DOMString name;
|
||||
DOMString namePrefix;
|
||||
// Maps unsigned shorts to BluetoothDataFilters.
|
||||
MozMap<BluetoothDataFilterInit> manufacturerData;
|
||||
record<DOMString, BluetoothDataFilterInit> manufacturerData;
|
||||
// Maps BluetoothServiceUUIDs to BluetoothDataFilters.
|
||||
MozMap<BluetoothDataFilterInit> serviceData;
|
||||
record<DOMString, BluetoothDataFilterInit> serviceData;
|
||||
};
|
||||
|
||||
dictionary RequestDeviceOptions {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
// https://fetch.spec.whatwg.org/#headers-class
|
||||
|
||||
typedef (Headers or sequence<sequence<ByteString>> or MozMap<ByteString>) HeadersInit;
|
||||
typedef (Headers or sequence<sequence<ByteString>> or record<DOMString, ByteString>) HeadersInit;
|
||||
|
||||
[Constructor(optional HeadersInit init),
|
||||
Exposed=(Window,Worker)]
|
||||
|
@ -434,33 +434,33 @@ interface TestBinding {
|
||||
sequence<sequence<long>> returnSequenceSequence();
|
||||
void passUnionSequenceSequence((long or sequence<sequence<long>>) seq);
|
||||
|
||||
void passMozMap(MozMap<long> arg);
|
||||
void passNullableMozMap(MozMap<long>? arg);
|
||||
void passMozMapOfNullableInts(MozMap<long?> arg);
|
||||
void passOptionalMozMapOfNullableInts(optional MozMap<long?> arg);
|
||||
void passOptionalNullableMozMapOfNullableInts(optional MozMap<long?>? arg);
|
||||
void passCastableObjectMozMap(MozMap<TestBinding> arg);
|
||||
void passNullableCastableObjectMozMap(MozMap<TestBinding?> arg);
|
||||
void passCastableObjectNullableMozMap(MozMap<TestBinding>? arg);
|
||||
void passNullableCastableObjectNullableMozMap(MozMap<TestBinding?>? arg);
|
||||
void passOptionalMozMap(optional MozMap<long> arg);
|
||||
void passOptionalNullableMozMap(optional MozMap<long>? arg);
|
||||
void passOptionalNullableMozMapWithDefaultValue(optional MozMap<long>? arg = null);
|
||||
void passOptionalObjectMozMap(optional MozMap<TestBinding> arg);
|
||||
void passStringMozMap(MozMap<DOMString> arg);
|
||||
void passByteStringMozMap(MozMap<ByteString> arg);
|
||||
void passMozMapOfMozMaps(MozMap<MozMap<long>> arg);
|
||||
void passMozMap(record<DOMString, long> arg);
|
||||
void passNullableMozMap(record<DOMString, long>? arg);
|
||||
void passMozMapOfNullableInts(record<DOMString, long?> arg);
|
||||
void passOptionalMozMapOfNullableInts(optional record<DOMString, long?> arg);
|
||||
void passOptionalNullableMozMapOfNullableInts(optional record<DOMString, long?>? arg);
|
||||
void passCastableObjectMozMap(record<DOMString, TestBinding> arg);
|
||||
void passNullableCastableObjectMozMap(record<DOMString, TestBinding?> arg);
|
||||
void passCastableObjectNullableMozMap(record<DOMString, TestBinding>? arg);
|
||||
void passNullableCastableObjectNullableMozMap(record<DOMString, TestBinding?>? arg);
|
||||
void passOptionalMozMap(optional record<DOMString, long> arg);
|
||||
void passOptionalNullableMozMap(optional record<DOMString, long>? arg);
|
||||
void passOptionalNullableMozMapWithDefaultValue(optional record<DOMString, long>? arg = null);
|
||||
void passOptionalObjectMozMap(optional record<DOMString, TestBinding> arg);
|
||||
void passStringMozMap(record<DOMString, DOMString> arg);
|
||||
void passByteStringMozMap(record<DOMString, ByteString> arg);
|
||||
void passMozMapOfMozMaps(record<DOMString, record<DOMString, long>> arg);
|
||||
|
||||
void passMozMapUnion((long or MozMap<ByteString>) init);
|
||||
void passMozMapUnion2((TestBinding or MozMap<ByteString>) init);
|
||||
void passMozMapUnion3((TestBinding or sequence<sequence<ByteString>> or MozMap<ByteString>) init);
|
||||
void passMozMapUnion((long or record<DOMString, ByteString>) init);
|
||||
void passMozMapUnion2((TestBinding or record<DOMString, ByteString>) init);
|
||||
void passMozMapUnion3((TestBinding or sequence<sequence<ByteString>> or record<DOMString, ByteString>) init);
|
||||
|
||||
MozMap<long> receiveMozMap();
|
||||
MozMap<long>? receiveNullableMozMap();
|
||||
MozMap<long?> receiveMozMapOfNullableInts();
|
||||
MozMap<long?>? receiveNullableMozMapOfNullableInts();
|
||||
MozMap<MozMap<long>> receiveMozMapOfMozMaps();
|
||||
MozMap<any> receiveAnyMozMap();
|
||||
record<DOMString, long> receiveMozMap();
|
||||
record<DOMString, long>? receiveNullableMozMap();
|
||||
record<DOMString, long?> receiveMozMapOfNullableInts();
|
||||
record<DOMString, long?>? receiveNullableMozMapOfNullableInts();
|
||||
record<DOMString, record<DOMString, long>> receiveMozMapOfMozMaps();
|
||||
record<DOMString, any> receiveAnyMozMap();
|
||||
|
||||
static attribute boolean booleanAttributeStatic;
|
||||
static void receiveVoidStatic();
|
||||
@ -519,7 +519,6 @@ interface TestBinding {
|
||||
Promise<any> returnRejectedPromise(any value);
|
||||
readonly attribute Promise<boolean> promiseAttribute;
|
||||
void acceptPromise(Promise<DOMString> string);
|
||||
void acceptNullablePromise(Promise<DOMString>? string);
|
||||
Promise<any> promiseNativeHandler(SimpleCallback? resolve, SimpleCallback? reject);
|
||||
void promiseResolveNative(Promise<any> p, any value);
|
||||
void promiseRejectNative(Promise<any> p, any value);
|
||||
|
Loading…
Reference in New Issue
Block a user