diff options
Diffstat (limited to 'dom/bindings')
22 files changed, 532 insertions, 235 deletions
diff --git a/dom/bindings/BindingDeclarations.h b/dom/bindings/BindingDeclarations.h index 24385c9fa5..c723af0021 100644 --- a/dom/bindings/BindingDeclarations.h +++ b/dom/bindings/BindingDeclarations.h @@ -131,11 +131,6 @@ template <class T> constexpr bool is_dom_union_with_typedarray_members = std::is_base_of_v<UnionWithTypedArraysBase, T>; -struct EnumEntry { - const char* value; - size_t length; -}; - enum class CallerType : uint32_t; class MOZ_STACK_CLASS GlobalObject { @@ -562,6 +557,13 @@ JS::Handle<JSObject*> GetPerInterfaceObjectHandle( JSContext* aCx, size_t aSlotId, CreateInterfaceObjectsMethod aCreator, bool aDefineOnGlobal); +namespace binding_detail { + +template <typename Enum> +struct EnumStrings; + +} // namespace binding_detail + } // namespace dom } // namespace mozilla diff --git a/dom/bindings/BindingIPCUtils.h b/dom/bindings/BindingIPCUtils.h index 5598e5896b..5cf6edb7a7 100644 --- a/dom/bindings/BindingIPCUtils.h +++ b/dom/bindings/BindingIPCUtils.h @@ -6,9 +6,18 @@ #ifndef _mozilla_dom_BindingIPCUtils_h #define _mozilla_dom_BindingIPCUtils_h +#include "mozilla/EnumTypeTraits.h" #include "mozilla/dom/BindingDeclarations.h" #include "ipc/EnumSerializer.h" +namespace mozilla::dom { + +template <class Enum> +using WebIDLEnumSerializer = IPC::ContiguousEnumSerializerInclusive< + Enum, ContiguousEnumValues<Enum>::min, ContiguousEnumValues<Enum>::max>; + +} // namespace mozilla::dom + namespace IPC { template <> struct ParamTraits<mozilla::dom::CallerType> diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index df3c509ab7..dd7a42b670 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -24,6 +24,8 @@ #include "mozilla/Array.h" #include "mozilla/Assertions.h" #include "mozilla/DeferredFinalize.h" +#include "mozilla/EnumTypeTraits.h" +#include "mozilla/EnumeratedRange.h" #include "mozilla/UniquePtr.h" #include "mozilla/dom/BindingCallContext.h" #include "mozilla/dom/BindingDeclarations.h" @@ -1343,26 +1345,27 @@ inline bool EnumValueNotFound<true>(BindingCallContext& cx, deflated.get(), type); } +namespace binding_detail { + template <typename CharT> inline int FindEnumStringIndexImpl(const CharT* chars, size_t length, - const EnumEntry* values) { - int i = 0; - for (const EnumEntry* value = values; value->value; ++value, ++i) { - if (length != value->length) { + const Span<const nsLiteralCString>& values) { + for (size_t i = 0; i < values.Length(); ++i) { + const nsLiteralCString& value = values[i]; + if (length != value.Length()) { continue; } bool equal = true; - const char* val = value->value; for (size_t j = 0; j != length; ++j) { - if (unsigned(val[j]) != unsigned(chars[j])) { + if (unsigned(value.CharAt(j)) != unsigned(chars[j])) { equal = false; break; } } if (equal) { - return i; + return (int)i; } } @@ -1371,8 +1374,9 @@ inline int FindEnumStringIndexImpl(const CharT* chars, size_t length, template <bool InvalidValueFatal> inline bool FindEnumStringIndex(BindingCallContext& cx, JS::Handle<JS::Value> v, - const EnumEntry* values, const char* type, - const char* sourceDescription, int* index) { + const Span<const nsLiteralCString>& values, + const char* type, const char* sourceDescription, + int* index) { // JS_StringEqualsAscii is slow as molasses, so don't use it here. JS::Rooted<JSString*> str(cx, JS::ToString(cx, v)); if (!str) { @@ -1405,6 +1409,31 @@ inline bool FindEnumStringIndex(BindingCallContext& cx, JS::Handle<JS::Value> v, return EnumValueNotFound<InvalidValueFatal>(cx, str, type, sourceDescription); } +} // namespace binding_detail + +template <typename Enum, class StringT> +inline Maybe<Enum> StringToEnum(const StringT& aString) { + int index = binding_detail::FindEnumStringIndexImpl( + aString.BeginReading(), aString.Length(), + binding_detail::EnumStrings<Enum>::Values); + return index >= 0 ? Some(static_cast<Enum>(index)) : Nothing(); +} + +template <typename Enum> +inline const nsCString& GetEnumString(Enum stringId) { + MOZ_RELEASE_ASSERT( + static_cast<size_t>(stringId) < + mozilla::ArrayLength(binding_detail::EnumStrings<Enum>::Values)); + return binding_detail::EnumStrings<Enum>::Values[static_cast<size_t>( + stringId)]; +} + +template <typename Enum> +constexpr mozilla::detail::EnumeratedRange<Enum> MakeWebIDLEnumeratedRange() { + return MakeInclusiveEnumeratedRange(ContiguousEnumValues<Enum>::min, + ContiguousEnumValues<Enum>::max); +} + inline nsWrapperCache* GetWrapperCache(const ParentObject& aParentObject) { return aParentObject.mWrapperCache; } @@ -3255,6 +3284,7 @@ already_AddRefed<Promise> CreateRejectedPromiseFromThrownException( } // namespace binding_detail } // namespace dom + } // namespace mozilla #endif /* mozilla_dom_BindingUtils_h__ */ diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index bf736e9ac2..7eed2593aa 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1006,6 +1006,18 @@ DOMInterfaces = { 'wrapperCache': False, }, +'TrustedHTML': { + 'wrapperCache': False, +}, + +'TrustedScript': { + 'wrapperCache': False, +}, + +'TrustedScriptURL': { + 'wrapperCache': False, +}, + 'UserInteraction': { 'nativeType': 'mozilla::telemetry::UserInteractionStopwatch', 'headerFile': 'mozilla/telemetry/Stopwatch.h', @@ -1527,6 +1539,10 @@ DOMInterfaces = { 'nativeType': 'mozilla::glean::GleanText', 'headerFile': 'mozilla/glean/bindings/Text.h', }, +'GleanObject': { + 'nativeType': 'mozilla::glean::GleanObject', + 'headerFile': 'mozilla/glean/bindings/Object.h', +}, 'Window': { 'nativeType': 'nsGlobalWindowInner', @@ -1962,6 +1978,11 @@ if buildconfig.substs.get("ENABLE_TESTS", False): 'register': False, }, + 'TestCallbackDictUnionOverload' : { + 'headerFile': 'TestBindingHeader.h', + 'register': False, + }, + }) if buildconfig.substs.get("MOZ_DEBUG", False): diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 80efa81ec5..7a6a28bffc 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -11,7 +11,6 @@ import re import string import textwrap -import six from Configuration import ( Descriptor, MemberIsLegacyUnforgeable, @@ -51,7 +50,6 @@ LEGACYCALLER_HOOK_NAME = "_legacycaller" RESOLVE_HOOK_NAME = "_resolve" MAY_RESOLVE_HOOK_NAME = "_mayResolve" NEW_ENUMERATE_HOOK_NAME = "_newEnumerate" -ENUM_ENTRY_VARIABLE_NAME = "strings" INSTANCE_RESERVED_SLOTS = 1 # This size is arbitrary. It is a power of 2 to make using it as a modulo @@ -247,12 +245,6 @@ def wantsGetWrapperCache(desc): ) -# We'll want to insert the indent at the beginnings of lines, but we -# don't want to indent empty lines. So only indent lines that have a -# non-newline character on them. -lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE) - - def indent(s, indentLevel=2): """ Indent C++ code. @@ -260,9 +252,16 @@ def indent(s, indentLevel=2): Weird secret feature: this doesn't indent lines that start with # (such as #include lines or #ifdef/#endif). """ - if s == "": - return s - return re.sub(lineStartDetector, indentLevel * " ", s) + + # We'll want to insert the indent at the beginnings of lines, but we + # don't want to indent empty lines. + padding = indentLevel * " " + return "\n".join( + [ + (padding + line) if line and line[0] != "#" else line + for line in s.split("\n") + ] + ) # dedent() and fill() are often called on the same string multiple @@ -1600,7 +1599,7 @@ class CGHeaders(CGWrapper): def getDeclarationFilename(decl): # Use our local version of the header, not the exported one, so that # test bindings, which don't export, will work correctly. - basename = os.path.basename(decl.filename()) + basename = os.path.basename(decl.filename) return basename.replace(".webidl", "Binding.h") @staticmethod @@ -7046,7 +7045,10 @@ def getJSToNativeConversionInfo( """ { int index; - if (!FindEnumStringIndex<${invalidEnumValueFatal}>(cx, $${val}, ${values}, "${enumtype}", "${sourceDescription}", &index)) { + if (!binding_detail::FindEnumStringIndex<${invalidEnumValueFatal}>(cx, $${val}, + binding_detail::EnumStrings<${enumtype}>::Values, + "${enumtype}", "${sourceDescription}", + &index)) { $*{exceptionCode} } $*{handleInvalidEnumValueCode} @@ -7054,7 +7056,6 @@ def getJSToNativeConversionInfo( } """, enumtype=enumName, - values=enumName + "Values::" + ENUM_ENTRY_VARIABLE_NAME, invalidEnumValueFatal=toStringBool(invalidEnumValueFatal), handleInvalidEnumValueCode=handleInvalidEnumValueCode, exceptionCode=exceptionCode, @@ -12330,20 +12331,13 @@ def getEnumValueName(value): raise SyntaxError('"_empty" is not an IDL enum value we support yet') if value == "": return "_empty" - nativeName = MakeNativeName(value) - if nativeName == "EndGuard_": - raise SyntaxError( - 'Enum value "' + value + '" cannot be used because it' - " collides with our internal EndGuard_ value. Please" - " rename our internal EndGuard_ to something else" - ) - return nativeName + return MakeNativeName(value) class CGEnumToJSValue(CGAbstractMethod): def __init__(self, enum): enumType = enum.identifier.name - self.stringsArray = enumType + "Values::" + ENUM_ENTRY_VARIABLE_NAME + self.stringsArray = "binding_detail::EnumStrings<" + enumType + ">::Values" CGAbstractMethod.__init__( self, None, @@ -12361,8 +12355,8 @@ class CGEnumToJSValue(CGAbstractMethod): """ MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(${strings})); JSString* resultStr = - JS_NewStringCopyN(aCx, ${strings}[uint32_t(aArgument)].value, - ${strings}[uint32_t(aArgument)].length); + JS_NewStringCopyN(aCx, ${strings}[uint32_t(aArgument)].BeginReading(), + ${strings}[uint32_t(aArgument)].Length()); if (!resultStr) { return false; } @@ -12377,80 +12371,54 @@ class CGEnum(CGThing): def __init__(self, enum): CGThing.__init__(self) self.enum = enum - entryDecl = fill( - """ - extern const EnumEntry ${entry_array}[${entry_count}]; - - static constexpr size_t Count = ${real_entry_count}; - - // Our "${entry_array}" contains an extra entry with a null string. - static_assert(mozilla::ArrayLength(${entry_array}) - 1 == Count, - "Mismatch between enum strings and enum count"); - - static_assert(static_cast<size_t>(${name}::EndGuard_) == Count, - "Mismatch between enum value and enum count"); - - inline auto GetString(${name} stringId) { - MOZ_ASSERT(static_cast<${type}>(stringId) < Count); - const EnumEntry& entry = ${entry_array}[static_cast<${type}>(stringId)]; - return Span<const char>{entry.value, entry.length}; - } - """, - entry_array=ENUM_ENTRY_VARIABLE_NAME, - entry_count=self.nEnumStrings(), - # -1 because nEnumStrings() includes a string for EndGuard_ - real_entry_count=self.nEnumStrings() - 1, - name=self.enum.identifier.name, - type=self.underlyingType(), - ) strings = CGNamespace( - self.stringsNamespace(), + "binding_detail", CGGeneric( - declare=entryDecl, + declare=fill( + """ + template <> struct EnumStrings<${name}> { + static const nsLiteralCString Values[${count}]; + }; + """, + name=self.enum.identifier.name, + count=self.nEnumStrings(), + ), define=fill( """ - extern const EnumEntry ${name}[${count}] = { - $*{entries} - { nullptr, 0 } - }; - """, - name=ENUM_ENTRY_VARIABLE_NAME, + const nsLiteralCString EnumStrings<${name}>::Values[${count}] = { + $*{entries} + }; + """, + name=self.enum.identifier.name, count=self.nEnumStrings(), - entries="".join( - '{"%s", %d},\n' % (val, len(val)) for val in self.enum.values() - ), + entries="".join('"%s"_ns,\n' % val for val in self.enum.values()), ), ), ) toJSValue = CGEnumToJSValue(enum) self.cgThings = CGList([strings, toJSValue], "\n") - def stringsNamespace(self): - return self.enum.identifier.name + "Values" - def nEnumStrings(self): - return len(self.enum.values()) + 1 + return len(self.enum.values()) - def underlyingType(self): - count = self.nEnumStrings() + @staticmethod + def underlyingType(enum): + count = len(enum.values()) if count <= 256: return "uint8_t" if count <= 65536: return "uint16_t" - raise ValueError( - "Enum " + self.enum.identifier.name + " has more than 65536 values" - ) + raise ValueError("Enum " + enum.identifier.name + " has more than 65536 values") def declare(self): decl = fill( """ enum class ${name} : ${ty} { $*{enums} - EndGuard_ }; """, name=self.enum.identifier.name, - ty=self.underlyingType(), + ty=CGEnum.underlyingType(self.enum), enums=",\n".join(map(getEnumValueName, self.enum.values())) + ",\n", ) @@ -12463,6 +12431,39 @@ class CGEnum(CGThing): return self.enum.getDeps() +class CGMaxContiguousEnumValue(CGThing): + def __init__(self, enum): + CGThing.__init__(self) + self.enum = enum + + def declare(self): + enumValues = self.enum.values() + return fill( + """ + template <> + struct MaxContiguousEnumValue<dom::${name}> + { + static constexpr dom::${name} value = dom::${name}::${maxValue}; + + static_assert(static_cast<${ty}>(dom::${name}::${minValue}) == 0, + "We rely on this in ContiguousEnumValues"); + static_assert(mozilla::ArrayLength(dom::binding_detail::EnumStrings<dom::${name}>::Values) - 1 == UnderlyingValue(value), + "Mismatch between enum strings and enum count"); + }; + """, + name=self.enum.identifier.name, + ty=CGEnum.underlyingType(self.enum), + maxValue=getEnumValueName(enumValues[-1]), + minValue=getEnumValueName(enumValues[0]), + ) + + def define(self): + return "" + + def deps(self): + return self.enum.getDeps() + + def getUnionAccessorSignatureType(type, descriptorProvider): """ Returns the types that are used in the getter and setter signatures for @@ -14867,7 +14868,7 @@ class CGCountMaybeMissingProperty(CGAbstractMethod): generate nested switches) or strings to use for case bodies. """ cases = [] - for label, body in sorted(six.iteritems(switchDecriptor["cases"])): + for label, body in sorted(switchDecriptor["cases"].items()): if isinstance(body, dict): body = self.gen_switch(body) cases.append( @@ -18412,7 +18413,7 @@ class CGGlobalNames(CGGeneric): ), ) - entries.append((name, nativeEntry)) + entries.append((name.encode(), nativeEntry)) # Unfortunately, when running tests, we may have no entries. # PerfectHash will assert if we give it an empty set of entries, so we @@ -18569,7 +18570,7 @@ class ForwardDeclarationBuilder: ] ) ) - for namespace, child in sorted(six.iteritems(self.children)): + for namespace, child in sorted(self.children.items()): decls.append(CGNamespace(namespace, child._build(atTopLevel=False))) cg = CGList(decls, "\n") @@ -19073,9 +19074,11 @@ class CGBindingRoot(CGThing): # Do codegen for all the enums enums = config.getEnums(webIDLFile) cgthings.extend(CGEnum(e) for e in enums) + maxEnumValues = CGList([CGMaxContiguousEnumValue(e) for e in enums], "\n") bindingDeclareHeaders["mozilla/Span.h"] = enums bindingDeclareHeaders["mozilla/ArrayUtils.h"] = enums + bindingDeclareHeaders["mozilla/EnumTypeTraits.h"] = enums hasCode = descriptors or callbackDescriptors or dictionaries or callbacks bindingHeaders["mozilla/dom/BindingUtils.h"] = hasCode @@ -19175,7 +19178,13 @@ class CGBindingRoot(CGThing): curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n") # Wrap all of that in our namespaces. - curr = CGNamespace.build(["mozilla", "dom"], CGWrapper(curr, pre="\n")) + + if len(maxEnumValues) > 0: + curr = CGNamespace("dom", CGWrapper(curr, pre="\n")) + curr = CGWrapper(CGList([curr, maxEnumValues], "\n\n"), post="\n\n") + curr = CGNamespace("mozilla", CGWrapper(curr, pre="\n")) + else: + curr = CGNamespace.build(["mozilla", "dom"], CGWrapper(curr, pre="\n")) curr = CGList( [ @@ -19194,12 +19203,10 @@ class CGBindingRoot(CGThing): # Add header includes. bindingHeaders = [ - header for header, include in six.iteritems(bindingHeaders) if include + header for header, include in bindingHeaders.items() if include ] bindingDeclareHeaders = [ - header - for header, include in six.iteritems(bindingDeclareHeaders) - if include + header for header, include in bindingDeclareHeaders.items() if include ] curr = CGHeaders( @@ -24681,7 +24688,7 @@ class CGEventRoot(CGThing): self.root, pre=( AUTOGENERATED_WITH_SOURCE_WARNING_COMMENT - % os.path.basename(descriptor.interface.filename()) + % os.path.basename(descriptor.interface.filename) ), ) diff --git a/dom/bindings/Configuration.py b/dom/bindings/Configuration.py index 266a8db34a..354a450de6 100644 --- a/dom/bindings/Configuration.py +++ b/dom/bindings/Configuration.py @@ -7,7 +7,6 @@ import itertools import os from collections import defaultdict -import six from WebIDL import IDLIncludesStatement autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n" @@ -98,7 +97,7 @@ class Configuration(DescriptorProvider): # different .webidl file than their LHS interface. Make sure we # don't have any of those. See similar block below for partial # interfaces! - if thing.interface.filename() != thing.filename(): + if thing.interface.filename != thing.filename: raise TypeError( "The binding build system doesn't really support " "'includes' statements which don't appear in the " @@ -124,7 +123,7 @@ class Configuration(DescriptorProvider): # statements! if not thing.isExternal(): for partial in thing.getPartials(): - if partial.filename() != thing.filename(): + if partial.filename != thing.filename: raise TypeError( "The binding build system doesn't really support " "partial interfaces/namespaces/mixins which don't " @@ -146,7 +145,7 @@ class Configuration(DescriptorProvider): or iface.getExtendedAttribute("Func") == ["nsContentUtils::IsCallerChromeOrFuzzingEnabled"] or not iface.hasInterfaceObject() - or isInWebIDLRoot(iface.filename()) + or isInWebIDLRoot(iface.filename) ): raise TypeError( "Interfaces which are exposed to the web may only be " @@ -187,7 +186,7 @@ class Configuration(DescriptorProvider): self.descriptorsByFile = {} for d in self.descriptors: - self.descriptorsByFile.setdefault(d.interface.filename(), []).append(d) + self.descriptorsByFile.setdefault(d.interface.filename, []).append(d) self.enums = [e for e in parseData if e.isEnum()] @@ -212,19 +211,19 @@ class Configuration(DescriptorProvider): def addUnion(t): filenamesForUnion = self.filenamesPerUnion[t.name] - if t.filename() not in filenamesForUnion: + if t.filename not in filenamesForUnion: # We have a to be a bit careful: some of our built-in # typedefs are for unions, and those unions end up with # "<unknown>" as the filename. If that happens, we don't # want to try associating this union with one particular # filename, since there isn't one to associate it with, # really. - if t.filename() == "<unknown>": + if t.filename == "<unknown>": uniqueFilenameForUnion = None elif len(filenamesForUnion) == 0: # This is the first file that we found a union with this # name in, record the union as part of the file. - uniqueFilenameForUnion = t.filename() + uniqueFilenameForUnion = t.filename else: # We already found a file that contains a union with # this name. @@ -246,7 +245,7 @@ class Configuration(DescriptorProvider): # the filename as None, so that we can detect that. uniqueFilenameForUnion = None self.unionsPerFilename[uniqueFilenameForUnion].append(t) - filenamesForUnion.add(t.filename()) + filenamesForUnion.add(t.filename) def addUnions(t): t = findInnermostType(t) @@ -498,7 +497,7 @@ class Configuration(DescriptorProvider): # Collect up our filters, because we may have a webIDLFile filter that # we always want to apply first. tofilter = [(lambda x: x.interface.isExternal(), False)] - for key, val in six.iteritems(filters): + for key, val in filters.items(): if key == "webIDLFile": # Special-case this part to make it fast, since most of our # getDescriptors calls are conditioned on a webIDLFile. We may @@ -571,13 +570,13 @@ class Configuration(DescriptorProvider): return curr def getEnums(self, webIDLFile): - return [e for e in self.enums if e.filename() == webIDLFile] + return [e for e in self.enums if e.filename == webIDLFile] def getDictionaries(self, webIDLFile): - return [d for d in self.dictionaries if d.filename() == webIDLFile] + return [d for d in self.dictionaries if d.filename == webIDLFile] def getCallbacks(self, webIDLFile): - return [c for c in self.callbacks if c.filename() == webIDLFile] + return [c for c in self.callbacks if c.filename == webIDLFile] def getDescriptor(self, interfaceName): """ @@ -704,7 +703,7 @@ class Descriptor(DescriptorProvider): # import it here, sadly. # Use our local version of the header, not the exported one, so that # test bindings, which don't export, will work correctly. - basename = os.path.basename(self.interface.filename()) + basename = os.path.basename(self.interface.filename) headerDefault = basename.replace(".webidl", "Binding.h") else: if not self.interface.isExternal() and self.interface.getExtendedAttribute( diff --git a/dom/bindings/mozwebidlcodegen/__init__.py b/dom/bindings/mozwebidlcodegen/__init__.py index 8b6e62f345..3e8c6aa420 100644 --- a/dom/bindings/mozwebidlcodegen/__init__.py +++ b/dom/bindings/mozwebidlcodegen/__init__.py @@ -14,7 +14,6 @@ import os from copy import deepcopy import mozpack.path as mozpath -import six from mach.mixin.logging import LoggingMixin from mozbuild.makeutil import Makefile from mozbuild.pythonutil import iter_modules_in_path @@ -339,10 +338,8 @@ class WebIDLCodegenManager(LoggingMixin): if self._make_deps_path: mk = Makefile() codegen_rule = mk.create_rule([self._make_deps_target]) - codegen_rule.add_dependencies( - six.ensure_text(s) for s in global_hashes.keys() - ) - codegen_rule.add_dependencies(six.ensure_text(p) for p in self._input_paths) + codegen_rule.add_dependencies(global_hashes.keys()) + codegen_rule.add_dependencies(self._input_paths) with FileAvoidWrite(self._make_deps_path) as fh: mk.dump(fh) @@ -359,7 +356,12 @@ class WebIDLCodegenManager(LoggingMixin): example_paths = self._example_paths(interface) for path in example_paths: - print("Generating {}".format(path)) + self.log( + logging.INFO, + "webidl_generate_example_files", + {"filename": path}, + "Generating WebIDL example files derived from {filename}", + ) return self._maybe_write_codegen(root, *example_paths) @@ -380,7 +382,7 @@ class WebIDLCodegenManager(LoggingMixin): for path in sorted(self._input_paths): with io.open(path, "r", encoding="utf-8") as fh: data = fh.read() - hashes[path] = hashlib.sha1(six.ensure_binary(data)).hexdigest() + hashes[path] = hashlib.sha1(data.encode()).hexdigest() parser.parse(data, path) # Only these directories may contain WebIDL files with interfaces @@ -494,7 +496,7 @@ class WebIDLCodegenManager(LoggingMixin): for name in changedDictionaryNames: d = self._config.getDictionaryIfExists(name) if d: - changed_inputs.add(d.filename()) + changed_inputs.add(d.filename) # Only use paths that are known to our current state. # This filters out files that were deleted or changed type (e.g. from diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 9101e14cf2..43f9ec12f1 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -43,25 +43,22 @@ def parseInt(literal): return value * sign -def enum(*names, **kw): - class Foo(object): - attrs = OrderedDict() +# This is surprisingly faster than using the enum.IntEnum type (which doesn't +# support 'base' anyway) +def enum(*names, base=None): + if base is not None: + names = base.attrs + names - def __init__(self, names): - for v, k in enumerate(names): - self.attrs[k] = v - - def __getattr__(self, attr): - if attr in self.attrs: - return self.attrs[attr] - raise AttributeError + class CustomEnumType(object): + attrs = names def __setattr__(self, name, value): # this makes it read-only raise NotImplementedError - if "base" not in kw: - return Foo(names) - return Foo(chain(kw["base"].attrs.keys(), names)) + for v, k in enumerate(names): + setattr(CustomEnumType, k, v) + + return CustomEnumType() class WebIDLError(Exception): @@ -85,13 +82,10 @@ class Location(object): self._lineno = lineno self._lexpos = lexpos self._lexdata = lexer.lexdata - self._file = filename if filename else "<unknown>" + self.filename = filename if filename else "<unknown>" def __eq__(self, other): - return self._lexpos == other._lexpos and self._file == other._file - - def filename(self): - return self._file + return self._lexpos == other._lexpos and self.filename == other.filename def resolve(self): if self._line: @@ -110,7 +104,7 @@ class Location(object): def get(self): self.resolve() - return "%s line %s:%s" % (self._file, self._lineno, self._colno) + return "%s line %s:%s" % (self.filename, self._lineno, self._colno) def _pointerline(self): return " " * self._colno + "^" @@ -118,7 +112,7 @@ class Location(object): def __str__(self): self.resolve() return "%s line %s:%s\n%s\n%s" % ( - self._file, + self.filename, self._lineno, self._colno, self._line, @@ -129,13 +123,11 @@ class Location(object): class BuiltinLocation(object): def __init__(self, text): self.msg = text + "\n" + self.filename = "<builtin>" def __eq__(self, other): return isinstance(other, BuiltinLocation) and self.msg == other.msg - def filename(self): - return "<builtin>" - def resolve(self): pass @@ -153,9 +145,7 @@ class IDLObject(object): def __init__(self, location): self.location = location self.userData = dict() - - def filename(self): - return self.location.filename() + self.filename = location and location.filename def isInterface(self): return False @@ -220,8 +210,8 @@ class IDLObject(object): visited.add(self) deps = set() - if self.filename() != "<builtin>": - deps.add(self.filename()) + if self.filename != "<builtin>": + deps.add(self.filename) for d in self._getDependentObjects(): deps.update(d.getDeps(visited)) @@ -3032,6 +3022,9 @@ class IDLRecordType(IDLParametrizedType): if other.isUnion(): # Just forward to the union; it'll deal return other.isDistinguishableFrom(self) + if other.isCallback(): + # Let other determine if it's a LegacyTreatNonObjectAsNull callback + return other.isDistinguishableFrom(self) return ( other.isPrimitive() or other.isString() @@ -3490,7 +3483,7 @@ class IDLWrapperType(IDLType): or other.isSequence() or other.isRecord() ) - if self.isDictionary() and (other.nullable() or other.isUndefined()): + if self.isDictionary() and other.nullable(): return False if ( other.isPrimitive() @@ -3499,28 +3492,51 @@ class IDLWrapperType(IDLType): or other.isSequence() ): return True - if self.isDictionary(): + + # If this needs to handle other dictionary-like types we probably need + # some additional checks first. + assert self.isDictionaryLike() == ( + self.isDictionary() or self.isCallbackInterface() + ) + if self.isDictionaryLike(): + if other.isCallback(): + # Let other determine if it's a LegacyTreatNonObjectAsNull callback + return other.isDistinguishableFrom(self) + + assert ( + other.isNonCallbackInterface() + or other.isAny() + or other.isUndefined() + or other.isObject() + or other.isDictionaryLike() + ) + # At this point, dictionary-like (for 'self') and interface-like + # (for 'other') are the only two that are distinguishable. + # any is the union of all non-union types, so it's not distinguishable + # from other unions (because it is a union itself), or from all + # non-union types (because it has all of them as its members). return other.isNonCallbackInterface() - assert self.isInterface() - if other.isInterface(): + assert self.isNonCallbackInterface() + + if other.isUndefined() or other.isDictionaryLike() or other.isCallback(): + return True + + if other.isNonCallbackInterface(): if other.isSpiderMonkeyInterface(): # Just let |other| handle things return other.isDistinguishableFrom(self) + assert self.isGeckoInterface() and other.isGeckoInterface() if self.inner.isExternal() or other.unroll().inner.isExternal(): return self != other - return len( - self.inner.interfacesBasedOnSelf - & other.unroll().inner.interfacesBasedOnSelf - ) == 0 and (self.isNonCallbackInterface() or other.isNonCallbackInterface()) - if ( - other.isUndefined() - or other.isDictionary() - or other.isCallback() - or other.isRecord() - ): - return self.isNonCallbackInterface() + return ( + len( + self.inner.interfacesBasedOnSelf + & other.unroll().inner.interfacesBasedOnSelf + ) + == 0 + ) # Not much else |other| can be. # any is the union of all non-union types, so it's not distinguishable @@ -6067,6 +6083,9 @@ class IDLCallbackType(IDLType): if other.isUnion(): # Just forward to the union; it'll deal return other.isDistinguishableFrom(self) + # Callbacks without `LegacyTreatNonObjectAsNull` are distinguishable from Dictionary likes + if other.isDictionaryLike(): + return not self.callback._treatNonObjectAsNull return ( other.isUndefined() or other.isPrimitive() @@ -6943,7 +6962,7 @@ class IDLExtendedAttribute(IDLObject): class Tokenizer(object): - tokens = ["INTEGER", "FLOATLITERAL", "IDENTIFIER", "STRING", "WHITESPACE", "OTHER"] + tokens = ["INTEGER", "FLOATLITERAL", "IDENTIFIER", "STRING", "COMMENTS", "OTHER"] def t_FLOATLITERAL(self, t): r"(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+|Infinity))|NaN" @@ -6979,17 +6998,19 @@ class Tokenizer(object): t.value = t.value[1:-1] return t - def t_WHITESPACE(self, t): - r"[\t\n\r ]+|[\t\n\r ]*((//[^\n]*|/\*.*?\*/)[\t\n\r ]*)+" + t_ignore = "\t\n\r " + + def t_COMMENTS(self, t): + r"//[^\n]*|/\*(?s:.)*?\*/" pass def t_ELLIPSIS(self, t): r"\.\.\." - t.type = self.keywords.get(t.value) + t.type = "ELLIPSIS" return t def t_OTHER(self, t): - r"[^\t\n\r 0-9A-Z_a-z]" + r"[^0-9A-Z_a-z]" t.type = self.keywords.get(t.value, "OTHER") return t @@ -7086,14 +7107,14 @@ class Tokenizer(object): if lexer: self.lexer = lexer else: - self.lexer = lex.lex(object=self, reflags=re.DOTALL) + self.lexer = lex.lex(object=self) class SqueakyCleanLogger(object): errorWhitelist = [ - # Web IDL defines the WHITESPACE token, but doesn't actually + # Web IDL defines the COMMENTS token, but doesn't actually # use it ... so far. - "Token 'WHITESPACE' defined, but not used", + "Token 'COMMENTS' defined, but not used", # And that means we have an unused token "There is 1 unused token", # Web IDL defines a OtherOrComma rule that's only used in @@ -9097,13 +9118,8 @@ class Parser(Tokenizer): production.validate() # De-duplicate self._productions, without modifying its order. - seen = set() - result = [] - for p in self._productions: - if p not in seen: - seen.add(p) - result.append(p) - return result + result = dict.fromkeys(self._productions) + return list(result.keys()) def reset(self): return Parser(lexer=self.lexer) diff --git a/dom/bindings/parser/tests/test_builtin_filename.py b/dom/bindings/parser/tests/test_builtin_filename.py index 25ed32befc..97e8cb061f 100644 --- a/dom/bindings/parser/tests/test_builtin_filename.py +++ b/dom/bindings/parser/tests/test_builtin_filename.py @@ -8,4 +8,4 @@ def WebIDLTest(parser, harness): ) attr = parser.finish()[0].members[0] - harness.check(attr.type.filename(), "<builtin>", "Filename on builtin type") + harness.check(attr.type.filename, "<builtin>", "Filename on builtin type") diff --git a/dom/bindings/parser/tests/test_distinguishability.py b/dom/bindings/parser/tests/test_distinguishability.py index 8497490b1f..caf726c16b 100644 --- a/dom/bindings/parser/tests/test_distinguishability.py +++ b/dom/bindings/parser/tests/test_distinguishability.py @@ -228,7 +228,9 @@ def WebIDLTest(parser, harness): and (a != "any" and a != "Promise<any>" and a != "Promise<any>?") ] - unions = ["(long or Callback)", "(long or Dict)"] + unionsWithCallback = ["(long or Callback)"] + unionsNoCallback = ["(long or Dict)"] + unions = unionsWithCallback + unionsNoCallback numerics = ["long", "short", "long?", "short?"] booleans = ["boolean", "boolean?"] undefineds = ["undefined", "undefined?"] @@ -265,7 +267,7 @@ def WebIDLTest(parser, harness): "Date?", "any", "Promise<any>?", - ] + allBut(unions, ["(long or Callback)"]) + ] + unionsNoCallback sequences = ["sequence<long>", "sequence<short>"] nonUserObjects = nonObjects + interfaces + sequences otherObjects = allBut(argTypes, nonUserObjects + ["object"]) @@ -282,17 +284,14 @@ def WebIDLTest(parser, harness): "record<ByteString, long>", "record<UTF8String, long>", ] # JSString not supported in records - dictionaryLike = ( - [ - "Dict", - "Dict2", - "CallbackInterface", - "CallbackInterface?", - "CallbackInterface2", - ] - + records - + allBut(unions, ["(long or Callback)"]) - ) + dicts = ["Dict", "Dict2"] + callbacks = ["Callback", "Callback2"] + callbackInterfaces = [ + "CallbackInterface", + "CallbackInterface?", + "CallbackInterface2", + ] + dictionaryLike = dicts + callbackInterfaces + records + unionsNoCallback # Build a representation of the distinguishability table as a dict # of dicts, holding True values where needed, holes elsewhere. @@ -327,23 +326,60 @@ def WebIDLTest(parser, harness): setDistinguishable( "UnrelatedInterface", allBut(argTypes, ["object", "UnrelatedInterface"]) ) - setDistinguishable("CallbackInterface", allBut(nonUserObjects, undefineds)) setDistinguishable( - "CallbackInterface?", allBut(nonUserObjects, nullables + undefineds) + "CallbackInterface", + allBut(nonUserObjects + callbacks + unionsWithCallback, undefineds), + ) + setDistinguishable( + "CallbackInterface?", + allBut(nonUserObjects + callbacks + unionsWithCallback, nullables + undefineds), + ) + setDistinguishable( + "CallbackInterface2", + allBut(nonUserObjects + callbacks + unionsWithCallback, undefineds), ) - setDistinguishable("CallbackInterface2", allBut(nonUserObjects, undefineds)) setDistinguishable("object", nonObjects) - setDistinguishable("Callback", nonUserObjects) - setDistinguishable("Callback2", nonUserObjects) - setDistinguishable("Dict", allBut(nonUserObjects, nullables + undefineds)) - setDistinguishable("Dict2", allBut(nonUserObjects, nullables + undefineds)) - setDistinguishable("sequence<long>", allBut(argTypes, sequences + ["object"])) - setDistinguishable("sequence<short>", allBut(argTypes, sequences + ["object"])) - setDistinguishable("record<DOMString, object>", allBut(nonUserObjects, undefineds)) - setDistinguishable("record<USVString, Dict>", allBut(nonUserObjects, undefineds)) + setDistinguishable( + "Callback", + nonUserObjects + unionsNoCallback + dicts + records + callbackInterfaces, + ) + setDistinguishable( + "Callback2", + nonUserObjects + unionsNoCallback + dicts + records + callbackInterfaces, + ) + setDistinguishable( + "Dict", + allBut(nonUserObjects + unionsWithCallback + callbacks, nullables + undefineds), + ) + setDistinguishable( + "Dict2", + allBut(nonUserObjects + unionsWithCallback + callbacks, nullables + undefineds), + ) + setDistinguishable( + "sequence<long>", + allBut(argTypes, sequences + ["object"]), + ) + setDistinguishable( + "sequence<short>", + allBut(argTypes, sequences + ["object"]), + ) + setDistinguishable( + "record<DOMString, object>", + allBut(nonUserObjects + unionsWithCallback + callbacks, undefineds), + ) + setDistinguishable( + "record<USVString, Dict>", + allBut(nonUserObjects + unionsWithCallback + callbacks, undefineds), + ) # JSString not supported in records - setDistinguishable("record<ByteString, long>", allBut(nonUserObjects, undefineds)) - setDistinguishable("record<UTF8String, long>", allBut(nonUserObjects, undefineds)) + setDistinguishable( + "record<ByteString, long>", + allBut(nonUserObjects + unionsWithCallback + callbacks, undefineds), + ) + setDistinguishable( + "record<UTF8String, long>", + allBut(nonUserObjects + unionsWithCallback + callbacks, undefineds), + ) setDistinguishable("any", []) setDistinguishable("Promise<any>", []) setDistinguishable("Promise<any>?", []) @@ -358,9 +394,13 @@ def WebIDLTest(parser, harness): setDistinguishable( "Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]) ) - setDistinguishable("(long or Callback)", allBut(nonUserObjects, numerics)) setDistinguishable( - "(long or Dict)", allBut(nonUserObjects, numerics + nullables + undefineds) + "(long or Callback)", + allBut(nonUserObjects + dicts + records + callbackInterfaces, numerics), + ) + setDistinguishable( + "(long or Dict)", + allBut(nonUserObjects + callbacks, numerics + nullables + undefineds), ) def areDistinguishable(type1, type2): @@ -377,6 +417,7 @@ def WebIDLTest(parser, harness): callback interface CallbackInterface2 {}; callback Callback = any(); callback Callback2 = long(short arg); + [LegacyTreatNonObjectAsNull] callback LegacyCallback1 = any(); // Give our dictionaries required members so we don't need to // mess with optional and default values. dictionary Dict { required long member; }; diff --git a/dom/bindings/parser/tests/test_legacyTreatNonObjectAsNull.py b/dom/bindings/parser/tests/test_legacyTreatNonObjectAsNull.py new file mode 100644 index 0000000000..380ccdc4e7 --- /dev/null +++ b/dom/bindings/parser/tests/test_legacyTreatNonObjectAsNull.py @@ -0,0 +1,11 @@ +def WebIDLTest(parser, harness): + parser.parse( + """ + [LegacyTreatNonObjectAsNull] callback Function = any(any... arguments); + """ + ) + + results = parser.finish() + + callback = results[0] + harness.check(callback._treatNonObjectAsNull, True, "Got the expected value") diff --git a/dom/bindings/parser/tests/test_union_callback_dict.py b/dom/bindings/parser/tests/test_union_callback_dict.py new file mode 100644 index 0000000000..3e87e16ad4 --- /dev/null +++ b/dom/bindings/parser/tests/test_union_callback_dict.py @@ -0,0 +1,132 @@ +import WebIDL + + +def WebIDLTest(parser, harness): + parser = parser.reset() + threw = False + try: + parser.parse( + """ + dictionary TestDict { + DOMString member; + }; + [LegacyTreatNonObjectAsNull] callback TestCallback = undefined (); + typedef (TestCallback or TestDict) TestUnionCallbackDict; + """ + ) + results = parser.finish() + except WebIDL.WebIDLError: + threw = True + harness.ok( + threw, + "Should not allow Dict/Callback union where callback is [LegacyTreatNonObjectAsNull]", + ) + + parser = parser.reset() + + threw = False + try: + parser.parse( + """ + dictionary TestDict { + DOMString member; + }; + [LegacyTreatNonObjectAsNull] callback TestCallback = undefined (); + typedef (TestDict or TestCallback) TestUnionCallbackDict; + """ + ) + results = parser.finish() + except WebIDL.WebIDLError: + threw = True + harness.ok( + threw, + "Should not allow Dict/Callback union where callback is [LegacyTreatNonObjectAsNull]", + ) + + parser = parser.reset() + + parser.parse( + """ + dictionary TestDict { + DOMString member; + }; + callback TestCallback = undefined (); + typedef (TestCallback or TestDict) TestUnionCallbackDict; + """ + ) + results = parser.finish() + + harness.ok(True, "TestUnionCallbackDict interface parsed without error") + harness.check(len(results), 3, "Document should have 3 types") + + myDict = results[0] + harness.ok(isinstance(myDict, WebIDL.IDLDictionary), "Expect an IDLDictionary") + + myCallback = results[1] + harness.ok(isinstance(myCallback, WebIDL.IDLCallback), "Expect an IDLCallback") + + myUnion = results[2] + harness.ok(isinstance(myUnion, WebIDL.IDLTypedef), "Expect a IDLTypedef") + harness.ok( + isinstance(myUnion.innerType, WebIDL.IDLUnionType), "Expect a IDLUnionType" + ) + harness.ok( + isinstance(myUnion.innerType.memberTypes[0], WebIDL.IDLCallbackType), + "Expect a IDLCallbackType", + ) + harness.ok( + isinstance(myUnion.innerType.memberTypes[1], WebIDL.IDLWrapperType), + "Expect a IDLDictionary", + ) + harness.ok( + (myUnion.innerType.memberTypes[0].callback == myCallback), + "Expect left Union member to be MyCallback", + ) + harness.ok( + (myUnion.innerType.memberTypes[1].inner == myDict), + "Expect right Union member to be MyDict", + ) + + parser = parser.reset() + + parser.parse( + """ + dictionary TestDict { + DOMString member; + }; + callback TestCallback = undefined (); + typedef (TestDict or TestCallback) TestUnionCallbackDict; + """ + ) + results = parser.finish() + + harness.ok(True, "TestUnionCallbackDict interface parsed without error") + harness.check(len(results), 3, "Document should have 3 types") + + myDict = results[0] + harness.ok(isinstance(myDict, WebIDL.IDLDictionary), "Expect an IDLDictionary") + + myCallback = results[1] + harness.ok(isinstance(myCallback, WebIDL.IDLCallback), "Expect an IDLCallback") + + myUnion = results[2] + harness.ok(isinstance(myUnion, WebIDL.IDLTypedef), "Expect a IDLTypedef") + harness.ok( + isinstance(myUnion.innerType, WebIDL.IDLUnionType), "Expect a IDLUnionType" + ) + harness.ok( + isinstance(myUnion.innerType.memberTypes[0], WebIDL.IDLWrapperType), + "Expect a IDLDictionary", + ) + harness.ok( + isinstance(myUnion.innerType.memberTypes[1], WebIDL.IDLCallbackType), + "Expect a IDLCallbackType", + ) + harness.ok( + (myUnion.innerType.memberTypes[0].inner == myDict), + "Expect right Union member to be MyDict", + ) + harness.ok( + (myUnion.innerType.memberTypes[1].callback == myCallback), + "Expect left Union member to be MyCallback", + ) diff --git a/dom/bindings/test/TestBindingHeader.h b/dom/bindings/test/TestBindingHeader.h index 4a7ea91ee8..77053d9ba6 100644 --- a/dom/bindings/test/TestBindingHeader.h +++ b/dom/bindings/test/TestBindingHeader.h @@ -1798,6 +1798,20 @@ class TestPrefChromeOnlySCFuncConstructorForInterface : public nsISupports, Constructor(const GlobalObject&); }; +class TestCallbackDictUnionOverload : public nsISupports, + public nsWrapperCache { + public: + NS_DECL_ISUPPORTS + virtual nsISupports* GetParentObject(); + + void Overload1(bool); + void Overload1(TestCallback&); + void Overload1(const GrandparentDict&); + void Overload2(bool); + void Overload2(const GrandparentDict&); + void Overload2(TestCallback&); +}; + } // namespace dom } // namespace mozilla diff --git a/dom/bindings/test/TestCodeGen.webidl b/dom/bindings/test/TestCodeGen.webidl index 577be05920..827d9c35a7 100644 --- a/dom/bindings/test/TestCodeGen.webidl +++ b/dom/bindings/test/TestCodeGen.webidl @@ -1535,3 +1535,16 @@ interface TestPrefChromeOnlySCFuncConstructorForInterface { // in the generated constructor. constructor(); }; + +typedef (TestCallback or GrandparentDict) TestCallbackDictUnion; +typedef (GrandparentDict or TestCallback) TestDictCallbackUnion; + +[Exposed=Window] +interface TestCallbackDictUnionOverload { + undefined overload1(boolean arg); + undefined overload1(TestCallback arg); + undefined overload1(optional GrandparentDict arg = {}); + undefined overload2(boolean arg); + undefined overload2(optional GrandparentDict arg = {}); + undefined overload2(TestCallback arg); +}; diff --git a/dom/bindings/test/TestInterfaceJS.sys.mjs b/dom/bindings/test/TestInterfaceJS.sys.mjs index 53ce9d107d..ea229eda49 100644 --- a/dom/bindings/test/TestInterfaceJS.sys.mjs +++ b/dom/bindings/test/TestInterfaceJS.sys.mjs @@ -93,12 +93,12 @@ TestInterfaceJS.prototype = { pingPongNullableUnion(x) { return x; }, - returnBadUnion(x) { + returnBadUnion() { return 3; }, - testSequenceOverload(arg) {}, - testSequenceUnion(arg) {}, + testSequenceOverload() {}, + testSequenceUnion() {}, testThrowError() { throw new this._win.Error("We are an Error"); @@ -121,7 +121,7 @@ TestInterfaceJS.prototype = { throw Cr.NS_BINDING_ABORTED; }, - testThrowNsresultFromNative(x) { + testThrowNsresultFromNative() { // We want to throw an exception that we generate from an nsresult thrown // by a C++ component. Services.io.notImplemented(); diff --git a/dom/bindings/test/test_async_iterable.html b/dom/bindings/test/test_async_iterable.html index 8f1f04aea7..ed47ef4c9d 100644 --- a/dom/bindings/test/test_async_iterable.html +++ b/dom/bindings/test/test_async_iterable.html @@ -88,7 +88,7 @@ async function test_data_single() { let blockingPromises = []; for (let i = 0; i < 10; ++i) { let unblocker; - let promise = new Promise((resolve, reject) => { + let promise = new Promise((resolve) => { unblocker = resolve; }); unblockers.push(unblocker); diff --git a/dom/bindings/test/test_bug1123516_maplikesetlikechrome.xhtml b/dom/bindings/test/test_bug1123516_maplikesetlikechrome.xhtml index 724c40cbd3..be188b8fbe 100644 --- a/dom/bindings/test/test_bug1123516_maplikesetlikechrome.xhtml +++ b/dom/bindings/test/test_bug1123516_maplikesetlikechrome.xhtml @@ -50,9 +50,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1123516 ok(true, "Calling iterators via xrays should fail"); } - setlike.forEach((v,k,t) => { is(v, win.document.documentElement, "Cross-compartment forEach works"); }); + setlike.forEach((v) => { is(v, win.document.documentElement, "Cross-compartment forEach works"); }); TestInterfaceSetlikeNode.prototype.forEach.call(setlike, - (v,k,t) => { is(v, win.document.documentElement, "Cross-compartment forEach works"); }); + (v) => { is(v, win.document.documentElement, "Cross-compartment forEach works"); }); is(TestInterfaceSetlikeNode.prototype.delete.call(setlike, win.document.documentElement), true, "Cross-compartment unwrapping/comparison delete works"); /* eslint-disable-next-line no-shadow */ diff --git a/dom/bindings/test/test_observablearray.html b/dom/bindings/test/test_observablearray.html index 313fb67622..56e35eeca5 100644 --- a/dom/bindings/test/test_observablearray.html +++ b/dom/bindings/test/test_observablearray.html @@ -21,7 +21,7 @@ add_task(function testObservableArray_length() { let deleteCallbackTests = null; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback() { setCallbackCount++; }, deleteBooleanCallback(value, index) { @@ -82,10 +82,10 @@ add_task(function testObservableArray_length_callback_throw() { let deleteCallbackCount = 0; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback() { setCallbackCount++; }, - deleteBooleanCallback(value, index) { + deleteBooleanCallback(value) { deleteCallbackCount++; if (value) { throw new Error("deleteBooleanCallback"); @@ -268,7 +268,7 @@ add_task(function testObservableArray_setter_callback_throw() { throw new Error("setBooleanCallback"); } }, - deleteBooleanCallback(value, index) { + deleteBooleanCallback(value) { deleteCallbackCount++; if (value) { throw new Error("deleteBooleanCallback"); @@ -437,7 +437,7 @@ add_task(function testObservableArray_indexed_setter_callback_throw() { let deleteCallbackCount = 0; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback(value) { setCallbackCount++; if (value) { throw new Error("setBooleanCallback"); @@ -501,7 +501,7 @@ add_task(function testObservableArray_object() { is(index, callbackIndex++, "setCallbackTests: test index argument"); isDeeply(values[index], value, "setCallbackTests: test value argument"); }, - deleteObjectCallback(value, index) { + deleteObjectCallback() { deleteCallbackCount++; }, }); @@ -521,10 +521,10 @@ add_task(function testObservableArray_object() { add_task(function testObservableArray_xrays() { let m = new TestInterfaceObservableArray({ - setObjectCallback(value, index) { + setObjectCallback() { ok(false, "Shouldn't reach setObjectCallback"); }, - deleteObjectCallback(value, index) { + deleteObjectCallback() { ok(false, "Shouldn't reach deleteObjectCallback"); }, }); diff --git a/dom/bindings/test/test_observablearray_helper.html b/dom/bindings/test/test_observablearray_helper.html index d2b4897cac..e2f3e42c45 100644 --- a/dom/bindings/test/test_observablearray_helper.html +++ b/dom/bindings/test/test_observablearray_helper.html @@ -110,7 +110,7 @@ add_task(function testObservableArray_helper_replaceElementAt_callback_throw() { let deleteCallbackCount = 0; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback(value) { setCallbackCount++; if (value) { throw new Error("setBooleanCallback"); @@ -170,7 +170,7 @@ add_task(function testObservableArray_helper_appendElement() { setCallbackTests(value, index); } }, - deleteBooleanCallback(value, index) { + deleteBooleanCallback() { deleteCallbackCount++; }, }); @@ -211,13 +211,13 @@ add_task(function testObservableArray_helper_appendElement_callback_throw() { let deleteCallbackCount = 0; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback(value) { setCallbackCount++; if (value) { throw new Error("setBooleanCallback"); } }, - deleteBooleanCallback(value, index) { + deleteBooleanCallback() { deleteCallbackCount++; }, }); @@ -257,7 +257,7 @@ add_task(function testObservableArray_helper_removeLastElement() { let deleteCallbackTests = null; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback() { setCallbackCount++; }, deleteBooleanCallback(value, index) { @@ -316,10 +316,10 @@ add_task(function testObservableArray_helper_removeLastElement_callback_throw() let deleteCallbackCount = 0; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback() { setCallbackCount++; }, - deleteBooleanCallback(value, index) { + deleteBooleanCallback(value) { deleteCallbackCount++; if (value) { throw new Error("deleteBooleanCallback"); diff --git a/dom/bindings/test/test_observablearray_proxyhandler.html b/dom/bindings/test/test_observablearray_proxyhandler.html index d7d8810981..00ef7c26b4 100644 --- a/dom/bindings/test/test_observablearray_proxyhandler.html +++ b/dom/bindings/test/test_observablearray_proxyhandler.html @@ -184,7 +184,7 @@ add_task(function testObservableArrayExoticObjects_defineProperty_callback_throw const minLen = 3; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback(value) { setCallbackCount++; if (value) { throw new Error("setBooleanCallback"); @@ -300,7 +300,7 @@ add_task(function testObservableArrayExoticObjects_deleteProperty() { let deleteCallbackTests = null; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback() { setCallbackCount++; }, deleteBooleanCallback(value, index) { @@ -384,10 +384,10 @@ add_task(function testObservableArrayExoticObjects_deleteProperty_callback_throw let deleteCallbackCount = 0; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback() { setCallbackCount++; }, - deleteBooleanCallback(value, index) { + deleteBooleanCallback(value) { deleteCallbackCount++; if (value) { throw new Error("deleteBooleanCallback"); @@ -731,7 +731,7 @@ add_task(function testObservableArrayExoticObjects_set_callback_throw() { const minLen = 3; let m = new TestInterfaceObservableArray({ - setBooleanCallback(value, index) { + setBooleanCallback(value) { setCallbackCount++; if (value) { throw new Error("setBooleanCallback"); diff --git a/dom/bindings/test/test_promise_rejections_from_jsimplemented.html b/dom/bindings/test/test_promise_rejections_from_jsimplemented.html index ab7e15dc57..aba129dc3e 100644 --- a/dom/bindings/test/test_promise_rejections_from_jsimplemented.html +++ b/dom/bindings/test/test_promise_rejections_from_jsimplemented.html @@ -31,7 +31,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592 is(exn.stack, stack, "Should have the right stack in test " + testNumber); } - function ensurePromiseFail(testNumber, value) { + function ensurePromiseFail(testNumber) { ok(false, "Test " + testNumber + " should not have a fulfilled promise"); } diff --git a/dom/bindings/test/test_sequence_wrapping.html b/dom/bindings/test/test_sequence_wrapping.html index 34d901fb66..2b1d657b6c 100644 --- a/dom/bindings/test/test_sequence_wrapping.html +++ b/dom/bindings/test/test_sequence_wrapping.html @@ -37,7 +37,7 @@ function doTest() { win.Object.defineProperty(win.Array.prototype, "0", { - set(val) { + set() { setterCalled = true; }, }); |