aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2020-03-17 12:55:26 -0400
committerGitHub <noreply@github.com>2020-03-17 12:55:26 -0400
commit9fb83d81438d425e06d061f8ba0c4128c61fc1ac (patch)
tree17e6d29b9c3ed26de0f8b9d72c38fcad2445158a
parent59c68e2eb7afdda17fc27e866360a1746a78bbda (diff)
parent3f30c7d8be0c64d003a7e06ca044913801f2b1e0 (diff)
downloadservo-9fb83d81438d425e06d061f8ba0c4128c61fc1ac.tar.gz
servo-9fb83d81438d425e06d061f8ba0c4128c61fc1ac.zip
Auto merge of #25964 - servo:webidl, r=jdm
Update the WebIDL parser It now supports Python 3.
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py34
-rw-r--r--components/script/dom/bindings/codegen/parser/WebIDL.py315
-rw-r--r--components/script/dom/bindings/codegen/parser/ext-attribute-no-value-error.patch11
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py221
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_constructor.py71
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_date.py15
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py27
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py8
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py2
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_toJSON.py11
-rwxr-xr-xcomponents/script/dom/bindings/codegen/parser/update.sh6
11 files changed, 526 insertions, 195 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index f7ce60cc80c..fab5e1e713a 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -427,17 +427,6 @@ class CGMethodCall(CGThing):
(s[1][distinguishingIndex].type.isSequence() or
s[1][distinguishingIndex].type.isObject()))
- # Check for Date objects
- # XXXbz Do we need to worry about security wrappers around the Date?
- pickFirstSignature("%s.get().is_object() && "
- "{ rooted!(in(*cx) let obj = %s.get().to_object()); "
- "let mut is_date = false; "
- "assert!(ObjectIsDate(*cx, obj.handle(), &mut is_date)); "
- "is_date }" %
- (distinguishingArg, distinguishingArg),
- lambda s: (s[1][distinguishingIndex].type.isDate() or
- s[1][distinguishingIndex].type.isObject()))
-
# Check for vanilla JS objects
# XXXbz Do we need to worry about security wrappers?
pickFirstSignature("%s.get().is_object() && !is_platform_object(%s.get().to_object(), *cx)" %
@@ -596,8 +585,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# We should not have a defaultValue if we know we're an object
assert not isDefinitelyObject or defaultValue is None
- isEnforceRange = type.enforceRange
- isClamp = type.clamp
+ isEnforceRange = type.hasEnforceRange()
+ isClamp = type.hasClamp()
if type.treatNullAsEmpty:
treatNullAs = "EmptyString"
else:
@@ -1665,6 +1654,8 @@ class MethodDefiner(PropertyDefiner):
(maplikeOrSetlikeOrIterable and
maplikeOrSetlikeOrIterable.isIterable() and
maplikeOrSetlikeOrIterable.isValueIterator())):
+ m = maplikeOrSetlikeOrIterable
+
# Add our keys/values/entries/forEach
self.regular.append({
"name": "keys",
@@ -4162,8 +4153,6 @@ class CGMemberJITInfo(CGThing):
u.flatMemberTypes, "")
if t.isDictionary():
return "JSVAL_TYPE_OBJECT"
- if t.isDate():
- return "JSVAL_TYPE_OBJECT"
if not t.isPrimitive():
raise TypeError("No idea what type " + str(t) + " is.")
tag = t.tag()
@@ -4233,8 +4222,6 @@ class CGMemberJITInfo(CGThing):
u.flatMemberTypes, type)
if t.isDictionary():
return "JSJitInfo_ArgType::Object as i32"
- if t.isDate():
- return "JSJitInfo_ArgType::Object as i32"
if not t.isPrimitive():
raise TypeError("No idea what type " + str(t) + " is.")
tag = t.tag()
@@ -4540,13 +4527,6 @@ class CGUnionConversionStruct(CGThing):
else:
arrayObject = None
- dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
- if len(dateObjectMemberTypes) > 0:
- assert len(dateObjectMemberTypes) == 1
- raise TypeError("Can't handle dates in unions.")
- else:
- dateObject = None
-
callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
if len(callbackMemberTypes) > 0:
assert len(callbackMemberTypes) == 1
@@ -4582,10 +4562,10 @@ class CGUnionConversionStruct(CGThing):
else:
mozMapObject = None
- hasObjectTypes = object or interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject
+ hasObjectTypes = object or interfaceObject or arrayObject or callbackObject or mozMapObject
if hasObjectTypes:
# "object" is not distinguishable from other types
- assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject)
+ assert not object or not (interfaceObject or arrayObject or callbackObject or mozMapObject)
templateBody = CGList([], "\n")
if object:
templateBody.append(object)
@@ -6848,7 +6828,7 @@ def type_needs_tracing(t):
def is_typed_array(t):
assert isinstance(t, IDLObject), (t, type(t))
- return t.isTypedArray() or t.isArrayBuffer() or t.isArrayBufferView() or t.isSharedArrayBuffer()
+ return t.isTypedArray() or t.isArrayBuffer() or t.isArrayBufferView()
def type_needs_auto_root(t):
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
index b2e56c9deaf..223fd7efbb4 100644
--- a/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -481,9 +481,6 @@ class IDLExposureMixins():
def isExposedInWindow(self):
return 'Window' in self.exposureSet
- def isExposedOnMainThread(self):
- return self.isExposedInWindow()
-
def isExposedInAnyWorker(self):
return len(self.getWorkerExposureSet()) > 0
@@ -2090,9 +2087,9 @@ class IDLType(IDLObject):
'domstring',
'bytestring',
'usvstring',
+ 'utf8string',
'jsstring',
'object',
- 'date',
'void',
# Funny stuff
'interface',
@@ -2109,15 +2106,17 @@ class IDLType(IDLObject):
IDLObject.__init__(self, location)
self.name = name
self.builtin = False
- self.clamp = False
self.treatNullAsEmpty = False
- self.enforceRange = False
+ self._clamp = False
+ self._enforceRange = False
+ self._allowShared = False
self._extendedAttrDict = {}
def __eq__(self, other):
return (other and self.builtin == other.builtin and self.name == other.name and
- self.clamp == other.clamp and self.enforceRange == other.enforceRange and
- self.treatNullAsEmpty == other.treatNullAsEmpty)
+ self._clamp == other.hasClamp() and self._enforceRange == other.hasEnforceRange() and
+ self.treatNullAsEmpty == other.treatNullAsEmpty and
+ self._allowShared == other.hasAllowShared())
def __ne__(self, other):
return not self == other
@@ -2125,6 +2124,14 @@ class IDLType(IDLObject):
def __str__(self):
return str(self.name)
+ def prettyName(self):
+ """
+ A name that looks like what this type is named in the IDL spec. By default
+ this is just our .name, but types that have more interesting spec
+ representations should override this.
+ """
+ return str(self.name)
+
def isType(self):
return True
@@ -2152,6 +2159,9 @@ class IDLType(IDLObject):
def isUSVString(self):
return False
+ def isUTF8String(self):
+ return False
+
def isJSString(self):
return False
@@ -2173,12 +2183,12 @@ class IDLType(IDLObject):
def isArrayBufferView(self):
return False
- def isSharedArrayBuffer(self):
- return False
-
def isTypedArray(self):
return False
+ def isBufferSource(self):
+ return self.isArrayBuffer() or self.isArrayBufferView() or self.isTypedArray()
+
def isCallbackInterface(self):
return False
@@ -2195,10 +2205,7 @@ class IDLType(IDLObject):
def isSpiderMonkeyInterface(self):
""" Returns a boolean indicating whether this type is an 'interface'
type that is implemented in SpiderMonkey. """
- return self.isInterface() and (self.isArrayBuffer() or
- self.isArrayBufferView() or
- self.isSharedArrayBuffer() or
- self.isTypedArray() or
+ return self.isInterface() and (self.isBufferSource() or
self.isReadableStream())
def isDictionary(self):
@@ -2210,9 +2217,6 @@ class IDLType(IDLObject):
def isAny(self):
return self.tag() == IDLType.Tags.any
- def isDate(self):
- return self.tag() == IDLType.Tags.date
-
def isObject(self):
return self.tag() == IDLType.Tags.object
@@ -2235,6 +2239,15 @@ class IDLType(IDLObject):
def isJSONType(self):
return False
+ def hasClamp(self):
+ return self._clamp
+
+ def hasEnforceRange(self):
+ return self._enforceRange
+
+ def hasAllowShared(self):
+ return self._allowShared
+
def tag(self):
assert False # Override me!
@@ -2342,10 +2355,7 @@ class IDLNullableType(IDLParametrizedType):
assert not innerType.isVoid()
assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
- name = innerType.name
- if innerType.isComplete():
- name += "OrNull"
- IDLParametrizedType.__init__(self, location, name, innerType)
+ IDLParametrizedType.__init__(self, location, None, innerType)
def __eq__(self, other):
return isinstance(other, IDLNullableType) and self.inner == other.inner
@@ -2353,6 +2363,9 @@ class IDLNullableType(IDLParametrizedType):
def __str__(self):
return self.inner.__str__() + "OrNull"
+ def prettyName(self):
+ return self.inner.prettyName() + "?"
+
def nullable(self):
return True
@@ -2380,6 +2393,9 @@ class IDLNullableType(IDLParametrizedType):
def isUSVString(self):
return self.inner.isUSVString()
+ def isUTF8String(self):
+ return self.inner.isUTF8String()
+
def isJSString(self):
return self.inner.isJSString()
@@ -2410,9 +2426,6 @@ class IDLNullableType(IDLParametrizedType):
def isArrayBufferView(self):
return self.inner.isArrayBufferView()
- def isSharedArrayBuffer(self):
- return self.inner.isSharedArrayBuffer()
-
def isTypedArray(self):
return self.inner.isTypedArray()
@@ -2442,11 +2455,26 @@ class IDLNullableType(IDLParametrizedType):
def isJSONType(self):
return self.inner.isJSONType()
+ def hasClamp(self):
+ return self.inner.hasClamp()
+
+ def hasEnforceRange(self):
+ return self.inner.hasEnforceRange()
+
+ def hasAllowShared(self):
+ return self.inner.hasAllowShared()
+
+ def isComplete(self):
+ return self.name is not None
+
def tag(self):
return self.inner.tag()
def complete(self, scope):
- self.inner = self.inner.complete(scope)
+ if not self.inner.isComplete():
+ self.inner = self.inner.complete(scope)
+ assert self.inner.isComplete()
+
if self.inner.nullable():
raise WebIDLError("The inner type of a nullable type must not be "
"a nullable type",
@@ -2456,6 +2484,10 @@ class IDLNullableType(IDLParametrizedType):
raise WebIDLError("The inner type of a nullable type must not "
"be a union type that itself has a nullable "
"type as a member type", [self.location])
+ if self.inner.isDOMString():
+ if self.inner.treatNullAsEmpty:
+ raise WebIDLError("[TreatNullAs] not allowed on a nullable DOMString",
+ [self.location, self.inner.location])
self.name = self.inner.name + "OrNull"
return self
@@ -2469,6 +2501,13 @@ class IDLNullableType(IDLParametrizedType):
return False
return self.inner.isDistinguishableFrom(other)
+ def withExtendedAttributes(self, attrs):
+ # See https://github.com/heycam/webidl/issues/827#issuecomment-565131350
+ # Allowing extended attributes to apply to a nullable type is an intermediate solution.
+ # A potential longer term solution is to introduce a null type and get rid of nullables.
+ # For example, we could do `([Clamp] long or null) foo` in the future.
+ return IDLNullableType(self.location, self.inner.withExtendedAttributes(attrs))
+
class IDLSequenceType(IDLParametrizedType):
def __init__(self, location, parameterType):
@@ -2486,6 +2525,9 @@ class IDLSequenceType(IDLParametrizedType):
def __str__(self):
return self.inner.__str__() + "Sequence"
+ def prettyName(self):
+ return "sequence<%s>" % self.inner.prettyName()
+
def nullable(self):
return False
@@ -2504,6 +2546,9 @@ class IDLSequenceType(IDLParametrizedType):
def isUSVString(self):
return False
+ def isUTF8String(self):
+ return False
+
def isJSString(self):
return False
@@ -2540,8 +2585,7 @@ class IDLSequenceType(IDLParametrizedType):
# Just forward to the union; it'll deal
return other.isDistinguishableFrom(self)
return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isDate() or other.isInterface() or
- other.isDictionary() or
+ other.isInterface() or other.isDictionary() or
other.isCallback() or other.isRecord())
@@ -2565,6 +2609,9 @@ class IDLRecordType(IDLParametrizedType):
def __str__(self):
return self.keyType.__str__() + self.inner.__str__() + "Record"
+ def prettyName(self):
+ return "record<%s, %s>" % (self.keyType.prettyName(), self.inner.prettyName())
+
def isRecord(self):
return True
@@ -2592,7 +2639,7 @@ class IDLRecordType(IDLParametrizedType):
# Just forward to the union; it'll deal
return other.isDistinguishableFrom(self)
return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isDate() or other.isNonCallbackInterface() or other.isSequence())
+ other.isNonCallbackInterface() or other.isSequence())
def isExposedInAllOf(self, exposureSet):
return self.inner.unroll().isExposedInAllOf(exposureSet)
@@ -2614,6 +2661,9 @@ class IDLUnionType(IDLType):
assert self.isComplete()
return self.name.__hash__()
+ def prettyName(self):
+ return "(" + " or ".join(m.prettyName() for m in self.memberTypes) + ")"
+
def isVoid(self):
return False
@@ -2645,6 +2695,9 @@ class IDLUnionType(IDLType):
return typeName(type._identifier.object())
if isinstance(type, IDLObjectWithIdentifier):
return typeName(type.identifier)
+ if isinstance(type, IDLBuiltinType) and type.hasAllowShared():
+ assert type.isBufferSource()
+ return "MaybeShared" + type.name
return type.name
for (i, type) in enumerate(self.memberTypes):
@@ -2768,6 +2821,9 @@ class IDLTypedefType(IDLType):
def isUSVString(self):
return self.inner.isUSVString()
+ def isUTF8String(self):
+ return self.inner.isUTF8String()
+
def isJSString(self):
return self.inner.isJSString()
@@ -2795,9 +2851,6 @@ class IDLTypedefType(IDLType):
def isArrayBufferView(self):
return self.inner.isArrayBufferView()
- def isSharedArrayBuffer(self):
- return self.inner.isSharedArrayBuffer()
-
def isTypedArray(self):
return self.inner.isTypedArray()
@@ -2901,6 +2954,9 @@ class IDLWrapperType(IDLType):
def isUSVString(self):
return False
+ def isUTF8String(self):
+ return False
+
def isJSString(self):
return False
@@ -2976,11 +3032,11 @@ class IDLWrapperType(IDLType):
if self.isEnum():
return (other.isPrimitive() or other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isRecord() or other.isDate())
+ other.isSequence() or other.isRecord())
if self.isDictionary() and other.nullable():
return False
if (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isDate() or other.isSequence()):
+ other.isSequence()):
return True
if self.isDictionary():
return other.isNonCallbackInterface()
@@ -3052,6 +3108,9 @@ class IDLPromiseType(IDLParametrizedType):
def __str__(self):
return self.inner.__str__() + "Promise"
+ def prettyName(self):
+ return "Promise<%s>" % self.inner.prettyName()
+
def isPromise(self):
return True
@@ -3104,14 +3163,13 @@ class IDLBuiltinType(IDLType):
'domstring',
'bytestring',
'usvstring',
+ 'utf8string',
'jsstring',
'object',
- 'date',
'void',
# Funny stuff
'ArrayBuffer',
'ArrayBufferView',
- 'SharedArrayBuffer',
'Int8Array',
'Uint8Array',
'Uint8ClampedArray',
@@ -3142,13 +3200,12 @@ class IDLBuiltinType(IDLType):
Types.domstring: IDLType.Tags.domstring,
Types.bytestring: IDLType.Tags.bytestring,
Types.usvstring: IDLType.Tags.usvstring,
+ Types.utf8string: IDLType.Tags.utf8string,
Types.jsstring: IDLType.Tags.jsstring,
Types.object: IDLType.Tags.object,
- Types.date: IDLType.Tags.date,
Types.void: IDLType.Tags.void,
Types.ArrayBuffer: IDLType.Tags.interface,
Types.ArrayBufferView: IDLType.Tags.interface,
- Types.SharedArrayBuffer: IDLType.Tags.interface,
Types.Int8Array: IDLType.Tags.interface,
Types.Uint8Array: IDLType.Tags.interface,
Types.Uint8ClampedArray: IDLType.Tags.interface,
@@ -3161,11 +3218,48 @@ class IDLBuiltinType(IDLType):
Types.ReadableStream: IDLType.Tags.interface,
}
+ PrettyNames = {
+ Types.byte: "byte",
+ Types.octet: "octet",
+ Types.short: "short",
+ Types.unsigned_short: "unsigned short",
+ Types.long: "long",
+ Types.unsigned_long: "unsigned long",
+ Types.long_long: "long long",
+ Types.unsigned_long_long: "unsigned long long",
+ Types.boolean: "boolean",
+ Types.unrestricted_float: "unrestricted float",
+ Types.float: "float",
+ Types.unrestricted_double: "unrestricted double",
+ Types.double: "double",
+ Types.any: "any",
+ Types.domstring: "DOMString",
+ Types.bytestring: "ByteString",
+ Types.usvstring: "USVString",
+ Types.utf8string: "USVString", # That's what it is in spec terms
+ Types.jsstring: "USVString", # Again, that's what it is in spec terms
+ Types.object: "object",
+ Types.void: "void",
+ Types.ArrayBuffer: "ArrayBuffer",
+ Types.ArrayBufferView: "ArrayBufferView",
+ Types.Int8Array: "Int8Array",
+ Types.Uint8Array: "Uint8Array",
+ Types.Uint8ClampedArray: "Uint8ClampedArray",
+ Types.Int16Array: "Int16Array",
+ Types.Uint16Array: "Uint16Array",
+ Types.Int32Array: "Int32Array",
+ Types.Uint32Array: "Uint32Array",
+ Types.Float32Array: "Float32Array",
+ Types.Float64Array: "Float64Array",
+ Types.ReadableStream: "ReadableStream",
+ }
+
def __init__(self, location, name, type, clamp=False, enforceRange=False, treatNullAsEmpty=False,
- attrLocation=[]):
+ allowShared=False, attrLocation=[]):
"""
- The mutually exclusive clamp/enforceRange/treatNullAsEmpty arguments are used to create instances
- of this type with the appropriate attributes attached. Use .clamped(), .rangeEnforced(), and .treatNullAs().
+ The mutually exclusive clamp/enforceRange/treatNullAsEmpty/allowShared arguments are used
+ to create instances of this type with the appropriate attributes attached. Use .clamped(),
+ .rangeEnforced(), .withTreatNullAs() and .withAllowShared().
attrLocation is an array of source locations of these attributes for error reporting.
"""
@@ -3175,24 +3269,40 @@ class IDLBuiltinType(IDLType):
self._clamped = None
self._rangeEnforced = None
self._withTreatNullAs = None
- if self.isNumeric():
+ self._withAllowShared = None;
+ if self.isInteger():
if clamp:
- self.clamp = True
+ self._clamp = True
self.name = "Clamped" + self.name
self._extendedAttrDict["Clamp"] = True
elif enforceRange:
- self.enforceRange = True
+ self._enforceRange = True
self.name = "RangeEnforced" + self.name
self._extendedAttrDict["EnforceRange"] = True
elif clamp or enforceRange:
- raise WebIDLError("Non-numeric types cannot be [Clamp] or [EnforceRange]", attrLocation)
- if self.isDOMString():
+ raise WebIDLError("Non-integer types cannot be [Clamp] or [EnforceRange]", attrLocation)
+ if self.isDOMString() or self.isUTF8String():
if treatNullAsEmpty:
self.treatNullAsEmpty = True
self.name = "NullIsEmpty" + self.name
self._extendedAttrDict["TreatNullAs"] = ["EmptyString"]
elif treatNullAsEmpty:
raise WebIDLError("Non-string types cannot be [TreatNullAs]", attrLocation)
+ if self.isBufferSource():
+ if allowShared:
+ self._allowShared = True
+ self._extendedAttrDict["AllowShared"] = True
+ elif allowShared:
+ raise WebIDLError("Types that are not buffer source types cannot be [AllowShared]", attrLocation)
+
+ def __str__(self):
+ if self._allowShared:
+ assert self.isBufferSource()
+ return "MaybeShared" + str(self.name)
+ return str(self.name)
+
+ def prettyName(self):
+ return IDLBuiltinType.PrettyNames[self._typeTag]
def clamped(self, attrLocation):
if not self._clamped:
@@ -3215,6 +3325,13 @@ class IDLBuiltinType(IDLType):
attrLocation=attrLocation)
return self._withTreatNullAs
+ def withAllowShared(self, attrLocation):
+ if not self._withAllowShared:
+ self._withAllowShared = IDLBuiltinType(self.location, self.name,
+ self._typeTag, allowShared=True,
+ attrLocation=attrLocation)
+ return self._withAllowShared
+
def isPrimitive(self):
return self._typeTag <= IDLBuiltinType.Types.double
@@ -3228,6 +3345,7 @@ class IDLBuiltinType(IDLType):
return (self._typeTag == IDLBuiltinType.Types.domstring or
self._typeTag == IDLBuiltinType.Types.bytestring or
self._typeTag == IDLBuiltinType.Types.usvstring or
+ self._typeTag == IDLBuiltinType.Types.utf8string or
self._typeTag == IDLBuiltinType.Types.jsstring)
def isByteString(self):
@@ -3239,6 +3357,9 @@ class IDLBuiltinType(IDLType):
def isUSVString(self):
return self._typeTag == IDLBuiltinType.Types.usvstring
+ def isUTF8String(self):
+ return self._typeTag == IDLBuiltinType.Types.utf8string
+
def isJSString(self):
return self._typeTag == IDLBuiltinType.Types.jsstring
@@ -3251,9 +3372,6 @@ class IDLBuiltinType(IDLType):
def isArrayBufferView(self):
return self._typeTag == IDLBuiltinType.Types.ArrayBufferView
- def isSharedArrayBuffer(self):
- return self._typeTag == IDLBuiltinType.Types.SharedArrayBuffer
-
def isTypedArray(self):
return (self._typeTag >= IDLBuiltinType.Types.Int8Array and
self._typeTag <= IDLBuiltinType.Types.Float64Array)
@@ -3267,7 +3385,6 @@ class IDLBuiltinType(IDLType):
# all of it internally.
return (self.isArrayBuffer() or
self.isArrayBufferView() or
- self.isSharedArrayBuffer() or
self.isTypedArray() or
self.isReadableStream())
@@ -3305,27 +3422,22 @@ class IDLBuiltinType(IDLType):
return (other.isNumeric() or other.isString() or other.isEnum() or
other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isRecord() or other.isDate())
+ other.isSequence() or other.isRecord())
if self.isNumeric():
return (other.isBoolean() or other.isString() or other.isEnum() or
other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isRecord() or other.isDate())
+ other.isSequence() or other.isRecord())
if self.isString():
return (other.isPrimitive() or other.isInterface() or
other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isRecord() or other.isDate())
+ other.isSequence() or other.isRecord())
if self.isAny():
# Can't tell "any" apart from anything
return False
if self.isObject():
return other.isPrimitive() or other.isString() or other.isEnum()
- if self.isDate():
- return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isInterface() or other.isCallback() or
- other.isDictionary() or other.isSequence() or
- other.isRecord())
if self.isVoid():
return not other.isVoid()
# Not much else we could be!
@@ -3333,12 +3445,11 @@ class IDLBuiltinType(IDLType):
# Like interfaces, but we know we're not a callback
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isRecord() or other.isDate() or
+ other.isSequence() or other.isRecord() or
(other.isInterface() and (
# ArrayBuffer is distinguishable from everything
# that's not an ArrayBuffer or a callback interface
(self.isArrayBuffer() and not other.isArrayBuffer()) or
- (self.isSharedArrayBuffer() and not other.isSharedArrayBuffer()) or
(self.isReadableStream() and not other.isReadableStream()) or
# ArrayBufferView is distinguishable from everything
# that's not an ArrayBufferView or typed array.
@@ -3361,7 +3472,7 @@ class IDLBuiltinType(IDLType):
if not attribute.noArguments():
raise WebIDLError("[Clamp] must take no arguments",
[attribute.location])
- if ret.enforceRange or self.enforceRange:
+ if ret.hasEnforceRange() or self._enforceRange:
raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
[self.location, attribute.location])
ret = self.clamped([self.location, attribute.location])
@@ -3369,17 +3480,17 @@ class IDLBuiltinType(IDLType):
if not attribute.noArguments():
raise WebIDLError("[EnforceRange] must take no arguments",
[attribute.location])
- if ret.clamp or self.clamp:
+ if ret.hasClamp() or self._clamp:
raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
[self.location, attribute.location])
ret = self.rangeEnforced([self.location, attribute.location])
elif identifier == "TreatNullAs":
- if not self.isDOMString():
- raise WebIDLError("[TreatNullAs] only allowed on DOMStrings",
+ if not (self.isDOMString() or self.isUTF8String()):
+ raise WebIDLError("[TreatNullAs] only allowed on DOMStrings and UTF8Strings",
[self.location, attribute.location])
assert not self.nullable()
if not attribute.hasValue():
- raise WebIDLError("[TreatNullAs] must take an identifier argument"
+ raise WebIDLError("[TreatNullAs] must take an identifier argument",
[attribute.location])
value = attribute.value()
if value != 'EmptyString':
@@ -3387,6 +3498,15 @@ class IDLBuiltinType(IDLType):
"'EmptyString', not '%s'" % value,
[attribute.location])
ret = self.withTreatNullAs([self.location, attribute.location])
+ elif identifier == "AllowShared":
+ if not attribute.noArguments():
+ raise WebIDLError("[AllowShared] must take no arguments",
+ [attribute.location])
+ if not self.isBufferSource():
+ raise WebIDLError("[AllowShared] only allowed on buffer source types",
+ [self.location, attribute.location])
+ ret = self.withAllowShared([self.location, attribute.location])
+
else:
raise WebIDLError("Unhandled extended attribute on type",
[self.location, attribute.location])
@@ -3444,15 +3564,15 @@ BuiltinTypes = {
IDLBuiltinType.Types.usvstring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "USVString",
IDLBuiltinType.Types.usvstring),
+ IDLBuiltinType.Types.utf8string:
+ IDLBuiltinType(BuiltinLocation("<builtin type>"), "UTF8String",
+ IDLBuiltinType.Types.utf8string),
IDLBuiltinType.Types.jsstring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "JSString",
IDLBuiltinType.Types.jsstring),
IDLBuiltinType.Types.object:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object",
IDLBuiltinType.Types.object),
- IDLBuiltinType.Types.date:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "Date",
- IDLBuiltinType.Types.date),
IDLBuiltinType.Types.void:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Void",
IDLBuiltinType.Types.void),
@@ -3462,9 +3582,6 @@ BuiltinTypes = {
IDLBuiltinType.Types.ArrayBufferView:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBufferView",
IDLBuiltinType.Types.ArrayBufferView),
- IDLBuiltinType.Types.SharedArrayBuffer:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedArrayBuffer",
- IDLBuiltinType.Types.SharedArrayBuffer),
IDLBuiltinType.Types.Int8Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array",
IDLBuiltinType.Types.Int8Array),
@@ -3613,8 +3730,9 @@ class IDLValue(IDLObject):
# TreatNullAsEmpty is a different type for resolution reasons,
# however once you have a value it doesn't matter
return self
- elif self.type.isString() and (type.isByteString() or type.isJSString()):
- # Allow ByteStrings and JSStrings to use a default value like DOMString.
+ elif self.type.isString() and (type.isByteString() or type.isJSString() or type.isUTF8String()):
+ # Allow ByteStrings, UTF8String, and JSStrings to use a default
+ # value like DOMString.
# No coercion is required as Codegen.py will handle the
# extra steps. We want to make sure that our string contains
# only valid characters, so we check that here.
@@ -4307,8 +4425,9 @@ class IDLAttribute(IDLInterfaceMember):
assert not isinstance(t.name, IDLUnresolvedIdentifier)
self.type = t
- if self.readonly and (self.type.clamp or self.type.enforceRange or self.type.treatNullAsEmpty):
- raise WebIDLError("A readonly attribute cannot be [Clamp] or [EnforceRange]",
+ if self.readonly and (self.type.hasClamp() or self.type.hasEnforceRange() or
+ self.type.hasAllowShared() or self.type.treatNullAsEmpty):
+ raise WebIDLError("A readonly attribute cannot be [Clamp] or [EnforceRange] or [AllowShared]",
[self.location])
if self.type.isDictionary() and not self.getExtendedAttribute("Cached"):
raise WebIDLError("An attribute cannot be of a dictionary type",
@@ -4709,7 +4828,7 @@ class IDLArgument(IDLObjectWithIdentifier):
for attribute in attrs:
identifier = attribute.identifier()
if self.allowTypeAttributes and (identifier == "EnforceRange" or identifier == "Clamp" or
- identifier == "TreatNullAs"):
+ identifier == "TreatNullAs" or identifier == "AllowShared"):
self.type = self.type.withExtendedAttributes([attribute])
elif identifier == "TreatNonCallableAsNull":
self._allowTreatNonCallableAsNull = True
@@ -4879,8 +4998,7 @@ class IDLCallbackType(IDLType):
# Just forward to the union; it'll deal
return other.isDistinguishableFrom(self)
return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isNonCallbackInterface() or other.isDate() or
- other.isSequence())
+ other.isNonCallbackInterface() or other.isSequence())
def _getDependentObjects(self):
return self.callback._getDependentObjects()
@@ -5475,7 +5593,9 @@ class IDLConstructor(IDLMethod):
identifier == "ChromeOnly" or
identifier == "NewObject" or
identifier == "SecureContext" or
- identifier == "Throws"):
+ identifier == "Throws" or
+ identifier == "Func" or
+ identifier == "Pref"):
IDLMethod.handleExtendedAttribute(self, attr)
elif identifier == "HTMLConstructor":
if not attr.noArguments():
@@ -5675,11 +5795,11 @@ class Tokenizer(object):
"optional": "OPTIONAL",
"...": "ELLIPSIS",
"::": "SCOPE",
- "Date": "DATE",
"DOMString": "DOMSTRING",
"ByteString": "BYTESTRING",
"USVString": "USVSTRING",
"JSString": "JSSTRING",
+ "UTF8String": "UTF8STRING",
"any": "ANY",
"boolean": "BOOLEAN",
"byte": "BYTE",
@@ -5709,7 +5829,6 @@ class Tokenizer(object):
"<": "LT",
">": "GT",
"ArrayBuffer": "ARRAYBUFFER",
- "SharedArrayBuffer": "SHAREDARRAYBUFFER",
"or": "OR",
"maplike": "MAPLIKE",
"setlike": "SETLIKE",
@@ -6939,10 +7058,10 @@ class Parser(Tokenizer):
| EQUALS
| GT
| QUESTIONMARK
- | DATE
| DOMSTRING
| BYTESTRING
| USVSTRING
+ | UTF8STRING
| JSSTRING
| PROMISE
| ANY
@@ -7050,7 +7169,6 @@ class Parser(Tokenizer):
"""
DistinguishableType : PrimitiveType Null
| ARRAYBUFFER Null
- | SHAREDARRAYBUFFER Null
| READABLESTREAM Null
| OBJECT Null
"""
@@ -7058,8 +7176,6 @@ class Parser(Tokenizer):
type = BuiltinTypes[IDLBuiltinType.Types.object]
elif p[1] == "ArrayBuffer":
type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer]
- elif p[1] == "SharedArrayBuffer":
- type = BuiltinTypes[IDLBuiltinType.Types.SharedArrayBuffer]
elif p[1] == "ReadableStream":
type = BuiltinTypes[IDLBuiltinType.Types.ReadableStream]
else:
@@ -7122,13 +7238,6 @@ class Parser(Tokenizer):
type = IDLUnresolvedType(self.getLocation(p, 1), p[1])
p[0] = self.handleNullable(type, p[2])
- def p_DistinguishableTypeDate(self, p):
- """
- DistinguishableType : DATE Null
- """
- p[0] = self.handleNullable(BuiltinTypes[IDLBuiltinType.Types.date],
- p[2])
-
def p_ConstType(self, p):
"""
ConstType : PrimitiveType
@@ -7215,6 +7324,12 @@ class Parser(Tokenizer):
"""
p[0] = IDLBuiltinType.Types.usvstring
+ def p_BuiltinStringTypeUTF8String(self, p):
+ """
+ BuiltinStringType : UTF8STRING
+ """
+ p[0] = IDLBuiltinType.Types.utf8string
+
def p_BuiltinStringTypeJSString(self, p):
"""
BuiltinStringType : JSSTRING
@@ -7354,7 +7469,13 @@ class Parser(Tokenizer):
IdentifierList : IDENTIFIER Identifiers
"""
idents = list(p[2])
- idents.insert(0, p[1])
+ # This is only used for identifier-list-valued extended attributes, and if
+ # we're going to restrict to IDENTIFIER here we should at least allow
+ # escaping with leading '_' as usual for identifiers.
+ ident = p[1]
+ if ident[0] == '_':
+ ident = ident[1:]
+ idents.insert(0, ident)
p[0] = idents
def p_IdentifiersList(self, p):
@@ -7362,7 +7483,13 @@ class Parser(Tokenizer):
Identifiers : COMMA IDENTIFIER Identifiers
"""
idents = list(p[3])
- idents.insert(0, p[2])
+ # This is only used for identifier-list-valued extended attributes, and if
+ # we're going to restrict to IDENTIFIER here we should at least allow
+ # escaping with leading '_' as usual for identifiers.
+ ident = p[2]
+ if ident[0] == '_':
+ ident = ident[1:]
+ idents.insert(0, ident)
p[0] = idents
def p_IdentifiersEmpty(self, p):
diff --git a/components/script/dom/bindings/codegen/parser/ext-attribute-no-value-error.patch b/components/script/dom/bindings/codegen/parser/ext-attribute-no-value-error.patch
new file mode 100644
index 00000000000..210134d8ca6
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/ext-attribute-no-value-error.patch
@@ -0,0 +1,11 @@
+--- WebIDL.py
++++ WebIDL.py
+@@ -3490,7 +3490,7 @@ class IDLBuiltinType(IDLType):
+ [self.location, attribute.location])
+ assert not self.nullable()
+ if not attribute.hasValue():
+- raise WebIDLError("[TreatNullAs] must take an identifier argument"
++ raise WebIDLError("[TreatNullAs] must take an identifier argument",
+ [attribute.location])
+ value = attribute.value()
+ if value != 'EmptyString':
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py b/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py
index 43daca3c453..ff08791d16f 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py
@@ -25,6 +25,12 @@ def WebIDLTest(parser, harness):
void method2(optional [EnforceRange] long foo, optional [Clamp] long bar,
optional [TreatNullAs=EmptyString] DOMString baz);
};
+ interface C {
+ attribute [EnforceRange] long? foo;
+ attribute [Clamp] long? bar;
+ void method([EnforceRange] long? foo, [Clamp] long? bar);
+ void method2(optional [EnforceRange] long? foo, optional [Clamp] long? bar);
+ };
interface Setlike {
setlike<[Clamp] long>;
};
@@ -41,29 +47,105 @@ def WebIDLTest(parser, harness):
harness.ok(not threw, "Should not have thrown on parsing normal")
if not threw:
- harness.check(results[0].innerType.enforceRange, True, "Foo is [EnforceRange]")
- harness.check(results[1].innerType.clamp, True, "Bar is [Clamp]")
+ harness.check(results[0].innerType.hasEnforceRange(), True, "Foo is [EnforceRange]")
+ harness.check(results[1].innerType.hasClamp(), True, "Bar is [Clamp]")
harness.check(results[2].innerType.treatNullAsEmpty, True, "Baz is [TreatNullAs=EmptyString]")
A = results[3]
- harness.check(A.members[0].type.enforceRange, True, "A.a is [EnforceRange]")
- harness.check(A.members[1].type.clamp, True, "A.b is [Clamp]")
- harness.check(A.members[2].type.enforceRange, True, "A.c is [EnforceRange]")
- harness.check(A.members[3].type.enforceRange, True, "A.d is [EnforceRange]")
+ harness.check(A.members[0].type.hasEnforceRange(), True, "A.a is [EnforceRange]")
+ harness.check(A.members[1].type.hasClamp(), True, "A.b is [Clamp]")
+ harness.check(A.members[2].type.hasEnforceRange(), True, "A.c is [EnforceRange]")
+ harness.check(A.members[3].type.hasEnforceRange(), True, "A.d is [EnforceRange]")
B = results[4]
- harness.check(B.members[0].type.enforceRange, True, "B.typedefFoo is [EnforceRange]")
- harness.check(B.members[1].type.enforceRange, True, "B.foo is [EnforceRange]")
- harness.check(B.members[2].type.clamp, True, "B.bar is [Clamp]")
+ harness.check(B.members[0].type.hasEnforceRange(), True, "B.typedefFoo is [EnforceRange]")
+ harness.check(B.members[1].type.hasEnforceRange(), True, "B.foo is [EnforceRange]")
+ harness.check(B.members[2].type.hasClamp(), True, "B.bar is [Clamp]")
harness.check(B.members[3].type.treatNullAsEmpty, True, "B.baz is [TreatNullAs=EmptyString]")
method = B.members[4].signatures()[0][1]
- harness.check(method[0].type.enforceRange, True, "foo argument of method is [EnforceRange]")
- harness.check(method[1].type.clamp, True, "bar argument of method is [Clamp]")
+ harness.check(method[0].type.hasEnforceRange(), True, "foo argument of method is [EnforceRange]")
+ harness.check(method[1].type.hasClamp(), True, "bar argument of method is [Clamp]")
harness.check(method[2].type.treatNullAsEmpty, True, "baz argument of method is [TreatNullAs=EmptyString]")
method2 = B.members[5].signatures()[0][1]
- harness.check(method[0].type.enforceRange, True, "foo argument of method2 is [EnforceRange]")
- harness.check(method[1].type.clamp, True, "bar argument of method2 is [Clamp]")
+ harness.check(method[0].type.hasEnforceRange(), True, "foo argument of method2 is [EnforceRange]")
+ harness.check(method[1].type.hasClamp(), True, "bar argument of method2 is [Clamp]")
harness.check(method[2].type.treatNullAsEmpty, True, "baz argument of method2 is [TreatNullAs=EmptyString]")
+ C = results[5]
+ harness.ok(C.members[0].type.nullable(), "C.foo is nullable")
+ harness.ok(C.members[0].type.hasEnforceRange(), "C.foo has [EnforceRange]")
+ harness.ok(C.members[1].type.nullable(), "C.bar is nullable")
+ harness.ok(C.members[1].type.hasClamp(), "C.bar has [Clamp]")
+ method = C.members[2].signatures()[0][1]
+ harness.ok(method[0].type.nullable(), "foo argument of method is nullable")
+ harness.ok(method[0].type.hasEnforceRange(), "foo argument of method has [EnforceRange]")
+ harness.ok(method[1].type.nullable(), "bar argument of method is nullable")
+ harness.ok(method[1].type.hasClamp(), "bar argument of method has [Clamp]")
+ method2 = C.members[3].signatures()[0][1]
+ harness.ok(method2[0].type.nullable(), "foo argument of method2 is nullable")
+ harness.ok(method2[0].type.hasEnforceRange(), "foo argument of method2 has [EnforceRange]")
+ harness.ok(method2[1].type.nullable(), "bar argument of method2 is nullable")
+ harness.ok(method2[1].type.hasClamp(), "bar argument of method2 has [Clamp]")
+
+ # Test [AllowShared]
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ typedef [AllowShared] ArrayBufferView Foo;
+ dictionary A {
+ required [AllowShared] ArrayBufferView a;
+ [ChromeOnly, AllowShared] ArrayBufferView b;
+ Foo c;
+ };
+ interface B {
+ attribute Foo typedefFoo;
+ attribute [AllowShared] ArrayBufferView foo;
+ void method([AllowShared] ArrayBufferView foo);
+ void method2(optional [AllowShared] ArrayBufferView foo);
+ };
+ interface C {
+ attribute [AllowShared] ArrayBufferView? foo;
+ void method([AllowShared] ArrayBufferView? foo);
+ void method2(optional [AllowShared] ArrayBufferView? foo);
+ };
+ interface Setlike {
+ setlike<[AllowShared] ArrayBufferView>;
+ };
+ interface Maplike {
+ maplike<[Clamp] long, [AllowShared] ArrayBufferView>;
+ };
+ interface Iterable {
+ iterable<[Clamp] long, [AllowShared] ArrayBufferView>;
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(not threw, "Should not have thrown on parsing normal")
+ if not threw:
+ harness.ok(results[0].innerType.hasAllowShared(), "Foo is [AllowShared]")
+ A = results[1]
+ harness.ok(A.members[0].type.hasAllowShared(), "A.a is [AllowShared]")
+ harness.ok(A.members[1].type.hasAllowShared(), "A.b is [AllowShared]")
+ harness.ok(A.members[2].type.hasAllowShared(), "A.c is [AllowShared]")
+ B = results[2]
+ harness.ok(B.members[0].type.hasAllowShared(), "B.typedefFoo is [AllowShared]")
+ harness.ok(B.members[1].type.hasAllowShared(), "B.foo is [AllowShared]")
+ method = B.members[2].signatures()[0][1]
+ harness.ok(method[0].type.hasAllowShared(), "foo argument of method is [AllowShared]")
+ method2 = B.members[3].signatures()[0][1]
+ harness.ok(method2[0].type.hasAllowShared(), "foo argument of method2 is [AllowShared]")
+ C = results[3]
+ harness.ok(C.members[0].type.nullable(), "C.foo is nullable")
+ harness.ok(C.members[0].type.hasAllowShared(), "C.foo is [AllowShared]")
+ method = C.members[1].signatures()[0][1]
+ harness.ok(method[0].type.nullable(), "foo argument of method is nullable")
+ harness.ok(method[0].type.hasAllowShared(), "foo argument of method is [AllowShared]")
+ method2 = C.members[2].signatures()[0][1]
+ harness.ok(method2[0].type.nullable(), "foo argument of method2 is nullable")
+ harness.ok(method2[0].type.hasAllowShared(), "foo argument of method2 is [AllowShared]")
- ATTRIBUTES = [("[Clamp]", "long"), ("[EnforceRange]", "long"), ("[TreatNullAs=EmptyString]", "DOMString")]
+ ATTRIBUTES = [("[Clamp]", "long"), ("[EnforceRange]", "long"),
+ ("[TreatNullAs=EmptyString]", "DOMString"), ("[AllowShared]", "ArrayBufferView")]
TEMPLATES = [
("required dictionary members", """
dictionary Foo {
@@ -93,7 +175,54 @@ def WebIDLTest(parser, harness):
readonly attribute Bar baz;
};
typedef %s %s Bar;
- """)
+ """),
+ ("method", """
+ interface Foo {
+ %s %s foo();
+ };
+ """),
+ ("interface","""
+ %s
+ interface Foo {
+ attribute %s foo;
+ };
+ """),
+ ("partial interface","""
+ interface Foo {
+ void foo();
+ };
+ %s
+ partial interface Foo {
+ attribute %s bar;
+ };
+ """),
+ ("interface mixin","""
+ %s
+ interface mixin Foo {
+ attribute %s foo;
+ };
+ """),
+ ("namespace","""
+ %s
+ namespace Foo {
+ attribute %s foo;
+ };
+ """),
+ ("partial namespace","""
+ namespace Foo {
+ void foo();
+ };
+ %s
+ partial namespace Foo {
+ attribute %s bar;
+ };
+ """),
+ ("dictionary","""
+ %s
+ dictionary Foo {
+ %s foo;
+ };
+ """)
];
for (name, template) in TEMPLATES:
@@ -167,55 +296,91 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange] via typedefs")
+ TYPES = ["DOMString", "unrestricted float", "float", "unrestricted double", "double"]
+
+ for type in TYPES:
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ typedef [Clamp] %s Foo;
+ """ % type)
+ parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should not allow [Clamp] on %s" % type)
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ typedef [EnforceRange] %s Foo;
+ """ % type)
+ parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should not allow [EnforceRange] on %s" % type)
+
+
parser = parser.reset()
threw = False
try:
parser.parse("""
- typedef [Clamp] DOMString Foo;
+ typedef [TreatNullAs=EmptyString] long Foo;
""")
parser.finish()
except:
threw = True
- harness.ok(threw, "Should not allow [Clamp] on DOMString")
-
+ harness.ok(threw, "Should not allow [TreatNullAs] on long")
parser = parser.reset()
threw = False
try:
parser.parse("""
- typedef [EnforceRange] DOMString Foo;
+ typedef [TreatNullAs=EmptyString] JSString Foo;
""")
parser.finish()
except:
threw = True
- harness.ok(threw, "Should not allow [EnforceRange] on DOMString")
-
+ harness.ok(threw, "Should not allow [TreatNullAs] on JSString")
parser = parser.reset()
threw = False
try:
parser.parse("""
- typedef [TreatNullAs=EmptyString] long Foo;
+ typedef [TreatNullAs=EmptyString] DOMString? Foo;
""")
parser.finish()
except:
threw = True
- harness.ok(threw, "Should not allow [TreatNullAs] on long")
+ harness.ok(threw, "Should not allow [TreatNullAs] on nullable DOMString")
parser = parser.reset()
threw = False
try:
parser.parse("""
- typedef [TreatNullAs=EmptyString] JSString Foo;
+ typedef [AllowShared] DOMString Foo;
""")
- parser.finish()
+ results = parser.finish()
except:
threw = True
+ harness.ok(threw, "[AllowShared] only allowed on buffer source types")
- harness.ok(threw, "Should not allow [TreatNullAs] on JSString")
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ typedef [AllowShared=something] ArrayBufferView Foo;
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+ harness.ok(threw, "[AllowShared] must take no arguments")
parser = parser.reset()
threw = False
@@ -230,7 +395,7 @@ def WebIDLTest(parser, harness):
except:
threw = True
harness.ok(not threw, "Should allow type attributes on unresolved types")
- harness.check(results[0].members[0].signatures()[0][1][0].type.clamp, True,
+ harness.check(results[0].members[0].signatures()[0][1][0].type.hasClamp(), True,
"Unresolved types with type attributes should correctly resolve with attributes")
parser = parser.reset()
@@ -246,5 +411,5 @@ def WebIDLTest(parser, harness):
except:
threw = True
harness.ok(not threw, "Should allow type attributes on typedefs")
- harness.check(results[0].members[0].signatures()[0][1][0].type.clamp, True,
+ harness.check(results[0].members[0].signatures()[0][1][0].type.hasClamp(), True,
"Unresolved types that resolve to typedefs with attributes should correctly resolve with attributes")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor.py
index 721f9c2089e..83e1f4fc34f 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_constructor.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_constructor.py
@@ -11,9 +11,9 @@ def WebIDLTest(parser, harness):
harness.check(argument.variadic, variadic, "Argument has the right variadic value")
def checkMethod(method, QName, name, signatures,
- static=True, getter=False, setter=False,
- deleter=False, legacycaller=False, stringifier=False,
- chromeOnly=False, htmlConstructor=False):
+ static=True, getter=False, setter=False, deleter=False,
+ legacycaller=False, stringifier=False, chromeOnly=False,
+ htmlConstructor=False, secureContext=False, pref=None, func=None):
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.ok(method.isMethod(), "Method is a method")
@@ -30,6 +30,9 @@ def WebIDLTest(parser, harness):
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")
+ harness.check(method.getExtendedAttribute("Pref"), pref, "Method has the correct pref value")
+ harness.check(method.getExtendedAttribute("Func"), func, "Method has the correct func value")
+ harness.check(method.getExtendedAttribute("SecureContext") is not None, secureContext, "Method has the correct SecureContext value")
sigpairs = zip(method.signatures(), signatures)
for (gotSignature, expectedSignature) in sigpairs:
@@ -90,6 +93,21 @@ def WebIDLTest(parser, harness):
parser = parser.reset()
parser.parse("""
+ interface TestPrefConstructor {
+ [Pref="dom.webidl.test1"] constructor();
+ };
+ """)
+ 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(), "::TestPrefConstructor::constructor",
+ "constructor", [("TestPrefConstructor (Wrapper)", [])],
+ pref=["dom.webidl.test1"])
+
+ parser = parser.reset()
+ parser.parse("""
interface TestChromeOnlyConstructor {
[ChromeOnly] constructor();
};
@@ -105,6 +123,53 @@ def WebIDLTest(parser, harness):
parser = parser.reset()
parser.parse("""
+ interface TestSCConstructor {
+ [SecureContext] constructor();
+ };
+ """)
+ 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(), "::TestSCConstructor::constructor",
+ "constructor", [("TestSCConstructor (Wrapper)", [])],
+ secureContext=True)
+
+ parser = parser.reset()
+ parser.parse("""
+ interface TestFuncConstructor {
+ [Func="Document::IsWebAnimationsEnabled"] constructor();
+ };
+ """)
+ 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(), "::TestFuncConstructor::constructor",
+ "constructor", [("TestFuncConstructor (Wrapper)", [])],
+ func=["Document::IsWebAnimationsEnabled"])
+
+ parser = parser.reset()
+ parser.parse("""
+ interface TestPrefChromeOnlySCFuncConstructor {
+ [ChromeOnly, Pref="dom.webidl.test1", SecureContext, Func="Document::IsWebAnimationsEnabled"]
+ constructor();
+ };
+ """)
+ 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(), "::TestPrefChromeOnlySCFuncConstructor::constructor",
+ "constructor", [("TestPrefChromeOnlySCFuncConstructor (Wrapper)", [])],
+ func=["Document::IsWebAnimationsEnabled"], pref=["dom.webidl.test1"],
+ chromeOnly=True, secureContext=True)
+
+ parser = parser.reset()
+ parser.parse("""
interface TestHTMLConstructor {
[HTMLConstructor] constructor();
};
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_date.py b/components/script/dom/bindings/codegen/parser/tests/test_date.py
deleted file mode 100644
index 2bdfc95e14f..00000000000
--- a/components/script/dom/bindings/codegen/parser/tests/test_date.py
+++ /dev/null
@@ -1,15 +0,0 @@
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface WithDates {
- attribute Date foo;
- void bar(Date arg);
- void baz(sequence<Date> arg);
- };
- """)
-
- results = parser.finish()
- harness.ok(results[0].members[0].type.isDate(), "Should have Date")
- harness.ok(results[0].members[1].signatures()[0][1][0].type.isDate(),
- "Should have Date argument")
- harness.ok(not results[0].members[2].signatures()[0][1][0].type.isDate(),
- "Should have non-Date argument")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
index bd9996e34c9..505b36468d6 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
@@ -149,7 +149,7 @@ def WebIDLTest(parser, harness):
# Now let's test our whole distinguishability table
argTypes = [ "long", "short", "long?", "short?", "boolean",
- "boolean?", "DOMString", "ByteString", "Enum", "Enum2",
+ "boolean?", "DOMString", "ByteString", "UTF8String", "Enum", "Enum2",
"Interface", "Interface?",
"AncestorInterface", "UnrelatedInterface", "CallbackInterface",
"CallbackInterface?", "CallbackInterface2",
@@ -158,14 +158,12 @@ def WebIDLTest(parser, harness):
"record<DOMString, object>",
"record<USVString, Dict>",
"record<ByteString, long>",
- "Date", "Date?", "any",
- "Promise<any>", "Promise<any>?",
- "USVString", "JSString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
+ "record<UTF8String, long>",
+ "any", "Promise<any>", "Promise<any>?",
+ "USVString", "JSString", "ArrayBuffer", "ArrayBufferView",
"Uint8Array", "Uint16Array",
"(long or Callback)", "(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):
@@ -177,26 +175,24 @@ def WebIDLTest(parser, harness):
primitives = numerics + booleans
nonNumerics = allBut(argTypes, numerics + unions)
nonBooleans = allBut(argTypes, booleans)
- strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString", "JSString" ]
+ strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString", "JSString", "UTF8String" ]
nonStrings = allBut(argTypes, strings)
nonObjects = primitives + strings
objects = allBut(argTypes, nonObjects )
bufferSourceTypes = ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"]
- sharedBufferSourceTypes = ["SharedArrayBuffer"]
interfaces = [ "Interface", "Interface?", "AncestorInterface",
- "UnrelatedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
+ "UnrelatedInterface" ] + bufferSourceTypes
nullables = (["long?", "short?", "boolean?", "Interface?",
"CallbackInterface?", "Dict", "Dict2",
"Date?", "any", "Promise<any>?"] +
allBut(unions, [ "(long or Callback)" ]))
- dates = [ "Date", "Date?" ]
sequences = [ "sequence<long>", "sequence<short>" ]
- nonUserObjects = nonObjects + interfaces + dates + sequences
+ nonUserObjects = nonObjects + interfaces + sequences
otherObjects = allBut(argTypes, nonUserObjects + ["object"])
notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
- otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
+ otherObjects + sequences + bufferSourceTypes)
records = [ "record<DOMString, object>", "record<USVString, Dict>",
- "record<ByteString, long>" ] # JSString not supported in records
+ "record<ByteString, long>", "record<UTF8String, long>" ] # JSString not supported in records
# Build a representation of the distinguishability table as a dict
# of dicts, holding True values where needed, holes elsewhere.
@@ -215,6 +211,7 @@ def WebIDLTest(parser, harness):
setDistinguishable("boolean?", allBut(nonBooleans, nullables))
setDistinguishable("DOMString", nonStrings)
setDistinguishable("ByteString", nonStrings)
+ setDistinguishable("UTF8String", nonStrings)
setDistinguishable("USVString", nonStrings)
setDistinguishable("JSString", nonStrings)
setDistinguishable("Enum", nonStrings)
@@ -240,8 +237,7 @@ def WebIDLTest(parser, harness):
setDistinguishable("record<USVString, Dict>", nonUserObjects)
# JSString not supported in records
setDistinguishable("record<ByteString, long>", nonUserObjects)
- setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
- setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
+ setDistinguishable("record<UTF8String, long>", nonUserObjects)
setDistinguishable("any", [])
setDistinguishable("Promise<any>", [])
setDistinguishable("Promise<any>?", [])
@@ -249,7 +245,6 @@ def WebIDLTest(parser, harness):
setDistinguishable("ArrayBufferView", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]))
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("(long or Dict)",
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py b/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py
index 97184ec2478..144c945bc10 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py
@@ -56,9 +56,9 @@ def WebIDLTest(parser, harness):
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].type.clamp,
+ harness.ok(results[0].members[0].signatures()[0][1][0].type.hasClamp(),
"Should be clamped")
- harness.ok(not results[0].members[1].signatures()[0][1][0].type.clamp,
+ harness.ok(not results[0].members[1].signatures()[0][1][0].type.hasClamp(),
"Should not be clamped")
parser = parser.reset()
@@ -86,9 +86,9 @@ def WebIDLTest(parser, harness):
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].type.enforceRange,
+ harness.ok(results[0].members[0].signatures()[0][1][0].type.hasEnforceRange(),
"Should be enforceRange")
- harness.ok(not results[0].members[1].signatures()[0][1][0].type.enforceRange,
+ harness.ok(not results[0].members[1].signatures()[0][1][0].type.hasEnforceRange(),
"Should not be enforceRange")
parser = parser.reset()
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py b/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py
index 2b48b615dd4..8ba6771677a 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py
@@ -80,7 +80,7 @@ def checkEquivalent(iface, harness):
for attr in dir(type1):
if attr.startswith('_') or \
attr in ['nullable', 'builtin', 'filename', 'location',
- 'inner', 'QName', 'getDeps', 'name'] or \
+ 'inner', 'QName', 'getDeps', 'name', 'prettyName'] or \
(hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
continue
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py b/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py
index b8b4f796ccb..ad01330e65a 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py
@@ -85,7 +85,7 @@ def WebIDLTest(parser, harness):
JsonTypes = [ "byte", "octet", "short", "unsigned short", "long", "unsigned long", "long long",
"unsigned long long", "float", "unrestricted float", "double", "unrestricted double", "boolean",
- "DOMString", "ByteString", "USVString", "Enum", "InterfaceWithToJSON", "object" ]
+ "DOMString", "ByteString", "UTF8String", "USVString", "Enum", "InterfaceWithToJSON", "object" ]
nonJsonTypes = [ "InterfaceWithoutToJSON", "any", "Int8Array", "Int16Array", "Int32Array","Uint8Array",
"Uint16Array", "Uint32Array", "Uint8ClampedArray", "Float32Array", "Float64Array", "ArrayBuffer" ]
@@ -129,9 +129,12 @@ def WebIDLTest(parser, harness):
doTest("interface Test { record<DOMString, %s> toJSON(); };" % type, False,
"record<DOMString, %s> should be a JSON type" % type)
- doTest("interface Test { record<ByteString, %s> toJSON(); };" % type, False,
+ doTest("interface Test { record<ByteString, %s> toJSON(); };" % type, False,
"record<ByteString, %s> should be a JSON type" % type)
+ doTest("interface Test { record<UTF8String, %s> toJSON(); };" % type, False,
+ "record<UTF8String, %s> should be a JSON type" % type)
+
doTest("interface Test { record<USVString, %s> toJSON(); };" % type, False,
"record<USVString, %s> should be a JSON type" % type)
@@ -174,12 +177,12 @@ def WebIDLTest(parser, harness):
doTest("interface Test { record<USVString, %s> toJSON(); };" % type, True,
"record<USVString, %s> should not be a JSON type" % type)
-
+
if type != "any":
doTest("interface Foo { object toJSON(); }; "
"interface Test { (Foo or %s) toJSON(); };" % type, True,
"union containing a non-JSON type (%s) should not be a JSON type" % type)
-
+
doTest("interface test { %s? toJSON(); };" % type, True,
"Nullable type (%s) should not be a JSON type" % type)
diff --git a/components/script/dom/bindings/codegen/parser/update.sh b/components/script/dom/bindings/codegen/parser/update.sh
index fee9720ab2d..dd7803c940c 100755
--- a/components/script/dom/bindings/codegen/parser/update.sh
+++ b/components/script/dom/bindings/codegen/parser/update.sh
@@ -5,8 +5,8 @@ patch < callback-location.patch
patch < union-typedef.patch
patch < inline.patch
-wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
+wget https://hg.mozilla.org/mozilla-central/archive/tip.zip/dom/bindings/parser/tests/ -O tests.zip
rm -r tests
mkdir tests
-tar xvpf tests.tar.gz -C tests --strip-components=5
-rm tests.tar.gz WebIDL.py.orig
+unzip -d tests -j tests.zip
+rm tests.zip WebIDL.py.orig