Bug 1071615. Make codegen fail when "A implements B" appears on a Web IDL file different from the file A is defined in. r=khuey
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 24 Sep 2014 09:11:29 -0400
changeset 207027 16411120d562f0c53badb90b8108c19326427701
parent 207026 98da988a5ac1542aef97da9d069721c3da86e40b
child 207028 30468ed119a3864b4caa3121a3d84b22b1fa1892
push id27544
push userryanvm@gmail.com
push dateWed, 24 Sep 2014 21:10:36 +0000
treeherdermozilla-central@1735ff2bb23e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs1071615
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1071615. Make codegen fail when "A implements B" appears on a Web IDL file different from the file A is defined in. r=khuey
dom/bindings/Configuration.py
dom/bindings/parser/WebIDL.py
dom/bindings/test/TestJSImplGen.webidl
dom/webidl/Document.webidl
dom/webidl/Element.webidl
dom/webidl/Event.webidl
dom/webidl/GeometryUtils.webidl
dom/webidl/SVGFEFloodElement.webidl
dom/webidl/Text.webidl
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -1,13 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from WebIDL import IDLInterface, IDLExternalInterface
+from WebIDL import IDLInterface, IDLExternalInterface, IDLImplementsStatement
 import os
 
 autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
 
 class Configuration:
     """
     Represents global configuration state based on IDL parse data and
     the configuration file.
@@ -21,16 +21,35 @@ class Configuration:
 
         # Build descriptors for all the interfaces we have in the parse data.
         # This allows callers to specify a subset of interfaces by filtering
         # |parseData|.
         self.descriptors = []
         self.interfaces = {}
         self.maxProtoChainLength = 0;
         for thing in parseData:
+            if isinstance(thing, IDLImplementsStatement):
+                # Our build system doesn't support dep build involving
+                # addition/removal of "implements" statements that appear in a
+                # different .webidl file than their LHS interface.  Make sure we
+                # don't have any of those.
+                #
+                # But whitelist a RHS that is LegacyQueryInterface,
+                # since people shouldn't be adding any of those.
+                if (thing.implementor.filename() != thing.filename() and
+                    thing.implementee.identifier.name != "LegacyQueryInterface"):
+                    raise TypeError(
+                        "The binding build system doesn't really support "
+                        "'implements' statements which don't appear in the "
+                        "file in which the left-hand side of the statement is "
+                        "defined.  Don't do this unless your right-hand side "
+                        "is LegacyQueryInterface.\n"
+                        "%s\n"
+                        "%s" %
+                        (thing.location, thing.implementor.location))
             # Some toplevel things are sadly types, and those have an
             # isInterface that doesn't mean the same thing as IDLObject's
             # isInterface()...
             if (not isinstance(thing, IDLInterface) and
                 not isinstance(thing, IDLExternalInterface)):
                 continue
             iface = thing
             self.interfaces[iface.identifier.name] = iface
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -3985,18 +3985,21 @@ class IDLMethod(IDLInterfaceMember, IDLS
             deps.union(overload._getDependentObjects())
         return deps
 
 class IDLImplementsStatement(IDLObject):
     def __init__(self, location, implementor, implementee):
         IDLObject.__init__(self, location)
         self.implementor = implementor;
         self.implementee = implementee
+        self._finished = False
 
     def finish(self, scope):
+        if self._finished:
+            return
         assert(isinstance(self.implementor, IDLIdentifierPlaceholder))
         assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
         implementor = self.implementor.finish(scope)
         implementee = self.implementee.finish(scope)
         # NOTE: we depend on not setting self.implementor and
         # self.implementee here to keep track of the original
         # locations.
         if not isinstance(implementor, IDLInterface):
@@ -4011,16 +4014,18 @@ class IDLImplementsStatement(IDLObject):
             raise WebIDLError("Right-hand side of 'implements' is not an "
                               "interface",
                               [self.implementee.location])
         if implementee.isCallback():
             raise WebIDLError("Right-hand side of 'implements' is a callback "
                               "interface",
                               [self.implementee.location])
         implementor.addImplementedInterface(implementee)
+        self.implementor = implementor
+        self.implementee = implementee
 
     def validate(self):
         pass
 
     def addExtendedAttributes(self, attrs):
         assert len(attrs) == 0
 
 class IDLExtendedAttribute(IDLObject):
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -5,18 +5,16 @@
  */
 
 typedef TestJSImplInterface AnotherNameForTestJSImplInterface;
 typedef TestJSImplInterface YetAnotherNameForTestJSImplInterface;
 typedef TestJSImplInterface? NullableTestJSImplInterface;
 
 callback MyTestCallback = void();
 
-TestInterface implements ImplementedInterface;
-
 enum MyTestEnum {
   "a",
   "b"
 };
 
 // We don't support multiple constructors (bug 869268) or named constructors
 // for JS-implemented WebIDL.
 [Constructor(DOMString str, unsigned long num, boolean? boolArg,
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -355,8 +355,9 @@ partial interface Document {
   [ChromeOnly] readonly attribute boolean isSrcdocDocument;
 };
 
 Document implements XPathEvaluator;
 Document implements GlobalEventHandlers;
 Document implements TouchEventHandlers;
 Document implements ParentNode;
 Document implements OnErrorEventHandlerForNodes;
+Document implements GeometryUtils;
--- a/dom/webidl/Element.webidl
+++ b/dom/webidl/Element.webidl
@@ -214,8 +214,9 @@ partial interface Element {
   [Func="nsDocument::IsWebComponentsEnabled"]
   readonly attribute ShadowRoot? shadowRoot;
 };
 
 Element implements ChildNode;
 Element implements NonDocumentTypeChildNode;
 Element implements ParentNode;
 Element implements Animatable;
+Element implements GeometryUtils;
--- a/dom/webidl/Event.webidl
+++ b/dom/webidl/Event.webidl
@@ -61,9 +61,8 @@ partial interface Event {
 
   boolean getPreventDefault();
 };
 
 dictionary EventInit {
   boolean bubbles = false;
   boolean cancelable = false;
 };
-
--- a/dom/webidl/GeometryUtils.webidl
+++ b/dom/webidl/GeometryUtils.webidl
@@ -28,14 +28,11 @@ interface GeometryUtils {
   [Throws, Pref="layout.css.convertFromNode.enabled"]
   DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional ConvertCoordinateOptions options);
   [Throws, Pref="layout.css.convertFromNode.enabled"]
   DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options);
   [Throws, Pref="layout.css.convertFromNode.enabled"]
   DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options);
 };
 
-Text implements GeometryUtils;
-Element implements GeometryUtils;
 // PseudoElement implements GeometryUtils;
-Document implements GeometryUtils;
 
 typedef (Text or Element /* or PseudoElement */ or Document) GeometryNode;
--- a/dom/webidl/SVGFEFloodElement.webidl
+++ b/dom/webidl/SVGFEFloodElement.webidl
@@ -8,9 +8,9 @@
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface SVGFEFloodElement : SVGElement {
 };
 
-SVGFEMergeElement implements SVGFilterPrimitiveStandardAttributes;
+SVGFEFloodElement implements SVGFilterPrimitiveStandardAttributes;
--- a/dom/webidl/Text.webidl
+++ b/dom/webidl/Text.webidl
@@ -12,8 +12,10 @@
 
 [Constructor(optional DOMString data = "")]
 interface Text : CharacterData {
   [Throws]
   Text splitText(unsigned long offset);
   [Throws]
   readonly attribute DOMString wholeText;
 };
+
+Text implements GeometryUtils;