Bug 792059 - Add NeedsWindowsUndef extended attribute for constants; r?bz draft
authorKyle Machulis <kyle@nonpolynomial.com>
Mon, 23 Oct 2017 17:34:28 -0700
changeset 685591 de187ad41cbbc3c38c5042cc3af06155a714022e
parent 685590 ef23ebf4501bfb5d898e4304e6fcf7e4bad68faa
child 685592 3a25029cb1c490b6e47ce7144fd86b626ea0f6f7
push id85990
push userbmo:kyle@nonpolynomial.com
push dateTue, 24 Oct 2017 22:11:11 +0000
reviewersbz
bugs792059
milestone58.0a1
Bug 792059 - Add NeedsWindowsUndef extended attribute for constants; r?bz When defining WebIDL constants in C++, we may need to undefine some constant names that conflict with windows.h preprocessor defines. Doing this in the binding header is far easier than tracking down the include orders that may cause conflicts. MozReview-Commit-ID: A0UoYezIQs5
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
dom/bindings/test/TestBindingHeader.h
dom/bindings/test/TestCodeGen.webidl
dom/bindings/test/TestExampleGen.webidl
dom/bindings/test/TestJSImplGen.webidl
dom/webidl/WebGL2RenderingContext.webidl
dom/webidl/WebGLRenderingContext.webidl
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2850,16 +2850,18 @@ class CGConstDefinition(CGThing):
         name = CppKeywords.checkMethodName(IDLToCIdentifier(member.identifier.name))
         tag = member.value.type.tag()
         value = member.value.value
         if tag == IDLType.Tags.bool:
             value = toStringBool(member.value.value)
         self.const = "static const %s %s = %s;" % (builtinNames[tag],
                                                    name,
                                                    value)
+        if member.getExtendedAttribute("NeedsWindowsUndef"):
+            self.const = "#if defined(XP_WIN)\n#undef %s\n#endif\n%s" % (name, self.const)
 
     def declare(self):
         return self.const
 
     def define(self):
         return ""
 
     def deps(self):
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -3971,17 +3971,18 @@ class IDLConst(IDLInterfaceMember):
     def handleExtendedAttribute(self, attr):
         identifier = attr.identifier()
         if identifier == "Exposed":
             convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
         elif (identifier == "Pref" or
               identifier == "ChromeOnly" or
               identifier == "Func" or
               identifier == "SecureContext" or
-              identifier == "NonEnumerable"):
+              identifier == "NonEnumerable" or
+              identifier == "NeedsWindowsUndef"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on constant" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
     def _getDependentObjects(self):
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -22,16 +22,21 @@
 namespace mozilla {
 namespace dom {
 class TestExternalInterface;
 class Promise;
 } // namespace dom
 } // namespace mozilla
 
 // We don't export TestCodeGenBinding.h, but it's right in our parent dir.
+#if XP_WIN
+// If we're on windows, simulate including windows.h. This step will cause
+// compilation failure if NeedsWindowsUndef is not defined.
+#define NO_ERROR 0x1
+#endif
 #include "../TestCodeGenBinding.h"
 
 extern bool TestFuncControlledMember(JSContext*, JSObject*);
 
 namespace mozilla {
 namespace dom {
 
 // IID for nsRenamedInterface
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -978,16 +978,20 @@ interface TestInterface {
   // [NonEnumerable] tests
   [NonEnumerable]
   attribute boolean nonEnumerableAttr;
   [NonEnumerable]
   const boolean nonEnumerableConst = true;
   [NonEnumerable]
   void nonEnumerableMethod();
 
+  // [NeedsWindowsUndef] test generation
+  [NeedsWindowsUndef]
+  const unsigned long NO_ERROR = 0xffffffff;
+
   // If you add things here, add them to TestExampleGen and TestJSImplGen as well
 };
 
 interface TestParentInterface {
 };
 
 interface TestChildInterface : TestParentInterface {
 };
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -805,16 +805,20 @@ interface TestExampleInterface {
   // [NonEnumerable] tests
   [NonEnumerable]
   attribute boolean nonEnumerableAttr;
   [NonEnumerable]
   const boolean nonEnumerableConst = true;
   [NonEnumerable]
   void nonEnumerableMethod();
 
+  // [NeedsWindowsUndef] test generation
+  [NeedsWindowsUndef]
+  const unsigned long NO_ERROR = 0xffffffff;
+
   // If you add things here, add them to TestCodeGen and TestJSImplGen as well
 };
 
 interface TestExampleProxyInterface {
   getter long longIndexedGetter(unsigned long ix);
   setter creator void longIndexedSetter(unsigned long y, long z);
   readonly attribute unsigned long length;
   stringifier DOMString myStringifier();
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -825,16 +825,20 @@ interface TestJSImplInterface {
   // [NonEnumerable] tests
   [NonEnumerable]
   attribute boolean nonEnumerableAttr;
   [NonEnumerable]
   const boolean nonEnumerableConst = true;
   [NonEnumerable]
   void nonEnumerableMethod();
 
+  // [NeedsWindowsUndef] test generation
+  [NeedsWindowsUndef]
+  const unsigned long NO_ERROR = 0xffffffff;
+
   // If you add things here, add them to TestCodeGen as well
 };
 
 [NavigatorProperty="TestNavigator", JSImplementation="@mozilla.org/test;1"]
 interface TestNavigator {
 };
 
 [Constructor, NavigatorProperty="TestNavigatorWithConstructor", JSImplementation="@mozilla.org/test;1"]
--- a/dom/webidl/WebGL2RenderingContext.webidl
+++ b/dom/webidl/WebGL2RenderingContext.webidl
@@ -275,16 +275,17 @@ interface WebGL2RenderingContextBase
     const GLenum SYNC_FLAGS                                    = 0x9115;
     const GLenum SYNC_FENCE                                    = 0x9116;
     const GLenum SYNC_GPU_COMMANDS_COMPLETE                    = 0x9117;
     const GLenum UNSIGNALED                                    = 0x9118;
     const GLenum SIGNALED                                      = 0x9119;
     const GLenum ALREADY_SIGNALED                              = 0x911A;
     const GLenum TIMEOUT_EXPIRED                               = 0x911B;
     const GLenum CONDITION_SATISFIED                           = 0x911C;
+    [NeedsWindowsUndef]
     const GLenum WAIT_FAILED                                   = 0x911D;
     const GLenum SYNC_FLUSH_COMMANDS_BIT                       = 0x00000001;
     const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR                   = 0x88FE;
     const GLenum ANY_SAMPLES_PASSED                            = 0x8C2F;
     const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE               = 0x8D6A;
     const GLenum SAMPLER_BINDING                               = 0x8919;
     const GLenum RGB10_A2UI                                    = 0x906F;
     const GLenum INT_2_10_10_10_REV                            = 0x8D9F;
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -212,16 +212,17 @@ interface WebGLRenderingContextBase {
     const GLenum STENCIL_TEST                   = 0x0B90;
     const GLenum DEPTH_TEST                     = 0x0B71;
     const GLenum SCISSOR_TEST                   = 0x0C11;
     const GLenum POLYGON_OFFSET_FILL            = 0x8037;
     const GLenum SAMPLE_ALPHA_TO_COVERAGE       = 0x809E;
     const GLenum SAMPLE_COVERAGE                = 0x80A0;
 
     /* ErrorCode */
+    [NeedsWindowsUndef]
     const GLenum NO_ERROR                       = 0;
     const GLenum INVALID_ENUM                   = 0x0500;
     const GLenum INVALID_VALUE                  = 0x0501;
     const GLenum INVALID_OPERATION              = 0x0502;
     const GLenum OUT_OF_MEMORY                  = 0x0505;
 
     /* FrontFaceDirection */
     const GLenum CW                             = 0x0900;