mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
* Update WebIDL.py * Update WebIDL.py * Add builtin-array.patch * Fix CodegenRust.py and Configuration.py * Fix missing downcasts * mach fmt * Update check and comment to explain why we need this check * Update Global of DissimilarOriginWindow.webidl
878 lines
20 KiB
Python
878 lines
20 KiB
Python
import WebIDL
|
|
|
|
|
|
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'"
|
|
)
|
|
|
|
# Test partial dictionary.
|
|
parser = parser.reset()
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
long c;
|
|
long g;
|
|
};
|
|
partial dictionary A {
|
|
long h;
|
|
long d;
|
|
};
|
|
"""
|
|
)
|
|
results = parser.finish()
|
|
|
|
dict1 = results[0]
|
|
harness.check(len(dict1.members), 4, "Dict1 has four members")
|
|
harness.check(dict1.members[0].identifier.name, "c", "c should be first")
|
|
harness.check(dict1.members[1].identifier.name, "d", "d should come after c")
|
|
harness.check(dict1.members[2].identifier.name, "g", "g should come after d")
|
|
harness.check(dict1.members[3].identifier.name, "h", "h should be last")
|
|
|
|
# Now reset our parser
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Dict {
|
|
long prop = 5;
|
|
long prop;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Should not allow name duplication in a dictionary")
|
|
|
|
# Test no name duplication across normal and partial dictionary.
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
long prop = 5;
|
|
};
|
|
partial dictionary A {
|
|
long prop;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw, "Should not allow name duplication across normal and partial 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;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
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;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
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 {};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Should not allow cycles in dictionary inheritance chains")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
[LegacyNullToEmptyString] DOMString foo;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw, "Should not allow [LegacyNullToEmptyString] on dictionary members"
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(A arg);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Trailing dictionary arg must be optional")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional A arg);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Trailing dictionary arg must have a default value")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo((A or DOMString) arg);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Trailing union arg containing a dictionary must be optional")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional (A or DOMString) arg);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw, "Trailing union arg containing a dictionary must have a default value"
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(A arg1, optional long arg2);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional A arg1, optional long arg2);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Dictionary arg followed by optional arg must have default value")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(A arg1, optional long arg2, long arg3);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
not threw,
|
|
"Dictionary arg followed by non-optional arg doesn't have to be optional",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo((A or DOMString) arg1, optional long arg2);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw,
|
|
"Union arg containing dictionary followed by optional arg must " "be optional",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional (A or DOMString) arg1, optional long arg2);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw,
|
|
"Union arg containing dictionary followed by optional arg must "
|
|
"have a default value",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(A arg1, long arg2);
|
|
};
|
|
"""
|
|
)
|
|
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 {
|
|
undefined doFoo(optional A? arg1 = {});
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except Exception as x:
|
|
threw = x
|
|
|
|
harness.ok(threw, "Optional dictionary arg must not be nullable")
|
|
harness.ok(
|
|
"nullable" in str(threw),
|
|
"Must have the expected exception for optional nullable dictionary arg",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
required long x;
|
|
};
|
|
interface X {
|
|
undefined doFoo(A? arg1);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except Exception as x:
|
|
threw = x
|
|
|
|
harness.ok(threw, "Required dictionary arg must not be nullable")
|
|
harness.ok(
|
|
"nullable" in str(threw),
|
|
"Must have the expected exception for required nullable " "dictionary arg",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional (A or long)? arg1 = {});
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except Exception as x:
|
|
threw = x
|
|
|
|
harness.ok(threw, "Dictionary arg must not be in an optional nullable union")
|
|
harness.ok(
|
|
"nullable" in str(threw),
|
|
"Must have the expected exception for optional nullable union "
|
|
"arg containing dictionary",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
required long x;
|
|
};
|
|
interface X {
|
|
undefined doFoo((A or long)? arg1);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except Exception as x:
|
|
threw = x
|
|
|
|
harness.ok(threw, "Dictionary arg must not be in a required nullable union")
|
|
harness.ok(
|
|
"nullable" in str(threw),
|
|
"Must have the expected exception for required nullable union "
|
|
"arg containing dictionary",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(sequence<A?> arg1);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(not threw, "Nullable union should be allowed in a sequence argument")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional (A or long?) arg1);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
harness.ok(threw, "Dictionary must not be in a union with a nullable type")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional (long? or A) arg1);
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
harness.ok(threw, "A nullable type must not be in a union with a dictionary")
|
|
|
|
parser = parser.reset()
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
A? doFoo();
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
harness.ok(True, "Dictionary return value can be nullable")
|
|
|
|
parser = parser.reset()
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional A arg = {});
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
harness.ok(True, "Dictionary arg should actually parse")
|
|
|
|
parser = parser.reset()
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional (A or DOMString) arg = {});
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
harness.ok(True, "Union arg containing a dictionary should actually parse")
|
|
|
|
parser = parser.reset()
|
|
parser.parse(
|
|
"""
|
|
dictionary A {
|
|
};
|
|
interface X {
|
|
undefined doFoo(optional (A or DOMString) arg = "abc");
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
harness.ok(
|
|
True,
|
|
"Union arg containing a dictionary with string default should actually parse",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
Foo foo;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Member type must not be its Dictionary.")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo3 : Foo {
|
|
short d;
|
|
};
|
|
|
|
dictionary Foo2 : Foo3 {
|
|
boolean c;
|
|
};
|
|
|
|
dictionary Foo1 : Foo2 {
|
|
long a;
|
|
};
|
|
|
|
dictionary Foo {
|
|
Foo1 b;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw,
|
|
"Member type must not be a Dictionary that " "inherits from its Dictionary.",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
(Foo or DOMString)[]? b;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw,
|
|
"Member type must not be a Nullable type "
|
|
"whose inner type includes its Dictionary.",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
(DOMString or Foo) b;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw,
|
|
"Member type must not be a Union type, one of "
|
|
"whose member types includes its Dictionary.",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
sequence<sequence<sequence<Foo>>> c;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw,
|
|
"Member type must not be a Sequence type "
|
|
"whose element type includes its Dictionary.",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
(DOMString or Foo)[] d;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw,
|
|
"Member type must not be an Array type "
|
|
"whose element type includes its Dictionary.",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
Foo1 b;
|
|
};
|
|
|
|
dictionary Foo3 {
|
|
Foo d;
|
|
};
|
|
|
|
dictionary Foo2 : Foo3 {
|
|
short c;
|
|
};
|
|
|
|
dictionary Foo1 : Foo2 {
|
|
long a;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(
|
|
threw,
|
|
"Member type must not be a Dictionary, one of whose "
|
|
"members or inherited members has a type that includes "
|
|
"its Dictionary.",
|
|
)
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
};
|
|
|
|
dictionary Bar {
|
|
Foo? d;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Member type must not be a nullable dictionary")
|
|
|
|
parser = parser.reset()
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
unrestricted float urFloat = 0;
|
|
unrestricted float urFloat2 = 1.1;
|
|
unrestricted float urFloat3 = -1.1;
|
|
unrestricted float? urFloat4 = null;
|
|
unrestricted float infUrFloat = Infinity;
|
|
unrestricted float negativeInfUrFloat = -Infinity;
|
|
unrestricted float nanUrFloat = NaN;
|
|
|
|
unrestricted double urDouble = 0;
|
|
unrestricted double urDouble2 = 1.1;
|
|
unrestricted double urDouble3 = -1.1;
|
|
unrestricted double? urDouble4 = null;
|
|
unrestricted double infUrDouble = Infinity;
|
|
unrestricted double negativeInfUrDouble = -Infinity;
|
|
unrestricted double nanUrDouble = NaN;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
harness.ok(True, "Parsing default values for unrestricted types succeeded.")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
double f = Infinity;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Only unrestricted values can be initialized to Infinity")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
double f = -Infinity;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Only unrestricted values can be initialized to -Infinity")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
double f = NaN;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Only unrestricted values can be initialized to NaN")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
float f = Infinity;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Only unrestricted values can be initialized to Infinity")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
float f = -Infinity;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Only unrestricted values can be initialized to -Infinity")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
float f = NaN;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(threw, "Only unrestricted values can be initialized to NaN")
|
|
|
|
parser = parser.reset()
|
|
threw = False
|
|
try:
|
|
parser.parse(
|
|
"""
|
|
dictionary Foo {
|
|
long module;
|
|
};
|
|
"""
|
|
)
|
|
parser.finish()
|
|
except WebIDL.WebIDLError:
|
|
threw = True
|
|
|
|
harness.ok(not threw, "Should be able to use 'module' as a dictionary member name")
|