diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2020-03-17 12:55:26 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-17 12:55:26 -0400 |
commit | 9fb83d81438d425e06d061f8ba0c4128c61fc1ac (patch) | |
tree | 17e6d29b9c3ed26de0f8b9d72c38fcad2445158a | |
parent | 59c68e2eb7afdda17fc27e866360a1746a78bbda (diff) | |
parent | 3f30c7d8be0c64d003a7e06ca044913801f2b1e0 (diff) | |
download | servo-9fb83d81438d425e06d061f8ba0c4128c61fc1ac.tar.gz servo-9fb83d81438d425e06d061f8ba0c4128c61fc1ac.zip |
Auto merge of #25964 - servo:webidl, r=jdm
Update the WebIDL parser
It now supports Python 3.
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 |