From 3fbf49822e84cfb7403b742f1cd3223be9a0b2ce Mon Sep 17 00:00:00 2001 From: John Dai Date: Fri, 3 Feb 2017 11:44:09 +0800 Subject: [PATCH] Bug 1309147 - Part 1: Implement the support for CEReactions in WebIDL parser. r=bz MozReview-Commit-ID: Dw0CMgzXKKy --HG-- extra : rebase_source : 2254eae5076d4d51eff61d8ee1363075c3aeb13b extra : histedit_source : 618b4e46eb6b5ac1791bd4f762a97373c6b8e2b3 --- dom/bindings/parser/WebIDL.py | 18 ++ dom/bindings/parser/tests/test_cereactions.py | 162 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 dom/bindings/parser/tests/test_cereactions.py diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index ad713e4e7cd8..2c6f7be3f570 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -4097,6 +4097,11 @@ class IDLAttribute(IDLInterfaceMember): raise WebIDLError("Attribute returns a type that is not exposed " "everywhere where the attribute is exposed", [self.location]) + if self.getExtendedAttribute("CEReactions"): + if self.readonly: + raise WebIDLError("[CEReactions] is not allowed on " + "readonly attributes", + [self.location]) def handleExtendedAttribute(self, attr): identifier = attr.identifier() @@ -4283,6 +4288,10 @@ class IDLAttribute(IDLInterfaceMember): raise WebIDLError("[Unscopable] is only allowed on non-static " "attributes and operations", [attr.location, self.location]) + elif identifier == "CEReactions": + if not attr.noArguments(): + raise WebIDLError("[CEReactions] must take no arguments", + [attr.location]) elif (identifier == "Pref" or identifier == "Deprecated" or identifier == "SetterThrows" or @@ -5016,6 +5025,15 @@ class IDLMethod(IDLInterfaceMember, IDLScope): raise WebIDLError("[Unscopable] is only allowed on non-static " "attributes and operations", [attr.location, self.location]) + elif identifier == "CEReactions": + if not attr.noArguments(): + raise WebIDLError("[CEReactions] must take no arguments", + [attr.location]) + + if self.isSpecial() and not self.isSetter() and not self.isDeleter(): + raise WebIDLError("[CEReactions] is only allowed on operation, " + "attribute, setter, and deleter", + [attr.location, self.location]) elif (identifier == "Throws" or identifier == "CanOOM" or identifier == "NewObject" or diff --git a/dom/bindings/parser/tests/test_cereactions.py b/dom/bindings/parser/tests/test_cereactions.py new file mode 100644 index 000000000000..2f9397d903e5 --- /dev/null +++ b/dom/bindings/parser/tests/test_cereactions.py @@ -0,0 +1,162 @@ +def WebIDLTest(parser, harness): + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions(DOMString a)] void foo(boolean arg2); + }; + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown for [CEReactions] with an argument") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions(DOMString b)] readonly attribute boolean bar; + }; + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown for [CEReactions] with an argument") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions] attribute boolean bar; + }; + """) + + results = parser.finish() + except Exception, e: + harness.ok(False, "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" % e) + threw = True + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions] void foo(boolean arg2); + }; + """) + + results = parser.finish() + except Exception, e: + harness.ok(False, "Shouldn't have thrown for [CEReactions] used on regular operations. %s" % e) + threw = True + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions] readonly attribute boolean A; + }; + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown for [CEReactions] used on a readonly attribute") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [CEReactions] + interface Foo { + } + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown for [CEReactions] used on a interface") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions] getter any(DOMString name); + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, + "Should have thrown for [CEReactions] used on a named getter") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions] creator boolean (DOMString name, boolean value); + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, + "Should have thrown for [CEReactions] used on a named creator") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions] legacycaller double compute(double x); + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, + "Should have thrown for [CEReactions] used on a legacycaller") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions] stringifier DOMString (); + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, + "Should have thrown for [CEReactions] used on a stringifier") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface Foo { + [CEReactions] jsonifier; + }; + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown for [CEReactions] used on a jsonifier")