Bug 755080 part 1. Add infrastructure for binding codegen tests. r=khuey,peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 23 May 2012 12:44:48 -0400
changeset 94727 24f6cf7eece90529f71b3dfa33e2d375dae7a522
parent 94726 19623c5b3b692aba2926001a835040030212943f
child 94728 13e1c5f61e38632de960e33c66c3d4697e64c306
push id22751
push useremorley@mozilla.com
push dateThu, 24 May 2012 14:48:49 +0000
treeherdermozilla-central@2552b0541f87 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey, peterv
bugs755080
milestone15.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 755080 part 1. Add infrastructure for binding codegen tests. r=khuey,peterv
dom/Makefile.in
dom/bindings/Bindings.conf
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/Makefile.in
dom/bindings/test/Makefile.in
dom/bindings/test/TestBindingHeader.h
dom/bindings/test/TestCodeGen.webidl
dom/webidl/WebIDL.mk
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -72,18 +72,21 @@ DIRS += \
 endif
 
 ifdef MOZ_B2G_BT
 DIRS += \
   bluetooth \
   $(NULL)
 endif
 
+# bindings/test is here, because it needs to build after bindings/, and
+# we build subdirectories before ourselves.
 TEST_DIRS += \
   tests \
   imptests \
+  bindings/test \
   $(NULL)
 
 ifneq (,$(filter gtk2 cocoa windows android qt os2,$(MOZ_WIDGET_TOOLKIT)))
 TEST_DIRS += plugins/test
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -23,16 +23,17 @@
 #   * workers - Indicates whether the descriptor is intended to be used for
 #               worker threads (defaults to false).
 #   * customTrace - The native class will use a custom trace hook (defaults to
 #                   true for workers, false otherwise).
 #   * customFinalize - The native class will use a custom finalize hook
 #                      (defaults to true for workers, false otherwise).
 #   * notflattened - The native type does not have nsIClassInfo, so when
 #                    wrapping it the right IID needs to be passed in.
+#   * register - True if this binding should be registered.  Defaults to true.
 #
 #   The following fields are either a string, an array (defaults to an empty
 #   array) or a dictionary with three possible keys (all, getterOnly and
 #   setterOnly) each having such an array as the value
 #
 #   * infallible - attributes and methods specified in the .webidl file that
 #                  cannot fail and therefore do not require the final nsresult&
 #                  argument
@@ -232,9 +233,18 @@ DOMInterfaces = {
     'prefable': True
 },
 {
     'workers': True,
     'nativeType': 'mozilla::dom::workers::XMLHttpRequestUpload',
     'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestUpload.h'
 }],
 
+####################################
+# Test Interfaces of various sorts #
+####################################
+
+'TestInterface' : {
+        'nativeType': 'mozilla::dom::TestInterface',
+        'headerFile': 'TestBindingHeader.h',
+        'register': False
+        }
 }
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -360,19 +360,20 @@ class CGHeaders(CGWrapper):
         CGWrapper.__init__(self, child,
                            declarePre=_includeString(declareIncludes),
                            definePre=_includeString(sorted(set(defineIncludes) |
                                                            bindingIncludes |
                                                            bindingHeaders |
                                                            implementationIncludes)))
     @staticmethod
     def getInterfaceFilename(interface):
+        # 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(interface.filename())
-        return 'mozilla/dom/' + \
-               basename.replace('.webidl', 'Binding.h')
+        return basename.replace('.webidl', 'Binding.h')
 
 class Argument():
     """
     A class for outputting the type and name of an argument
     """
     def __init__(self, argType, name):
         self.argType = argType
         self.name = name
@@ -3245,17 +3246,18 @@ class CGRegisterProtos(CGAbstractMethod)
 #define REGISTER_PROTO(_dom_class) \\
   aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface);\n\n"""
     def _undefineMacro(self):
         return "\n#undef REGISTER_PROTO"
     def _registerProtos(self):
         lines = ["REGISTER_PROTO(%s);" % desc.name
                  for desc in self.config.getDescriptors(hasInterfaceObject=True,
                                                         isExternal=False,
-                                                        workers=False)]
+                                                        workers=False,
+                                                        register=True)]
         return '\n'.join(lines) + '\n'
     def definition_body(self):
         return self._defineMacro() + self._registerProtos() + self._undefineMacro()
 
 class CGBindingRoot(CGThing):
     """
     Root codegen class for binding generation. Instantiate the class, and call
     declare or define to generate header or cpp code (respectively).
@@ -3417,17 +3419,18 @@ struct PrototypeIDMap;
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
         defineIncludes = [CGHeaders.getInterfaceFilename(desc.interface)
                           for desc in config.getDescriptors(hasInterfaceObject=True,
-                                                            workers=False)]
+                                                            workers=False,
+                                                            register=True)]
         defineIncludes.append('nsScriptNameSpaceManager.h')
         curr = CGHeaders([], [], defineIncludes, curr)
 
         # Add include guards.
         curr = CGIncludeGuard('RegisterBindings', curr)
 
         # Done.
         return curr
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -88,16 +88,17 @@ class Descriptor:
         headerDefault = self.nativeType
         headerDefault = headerDefault.split("::")[-1] + ".h"
         self.headerFile = desc.get('headerFile', headerDefault)
 
         castableDefault = not self.interface.isCallback()
         self.castable = desc.get('castable', castableDefault)
 
         self.notflattened = desc.get('notflattened', False)
+        self.register = desc.get('register', True)
 
         # If we're concrete, we need to crawl our ancestor interfaces and mark
         # them as having a concrete descendant.
         self.concrete = desc.get('concrete', True)
         if self.concrete:
             iface = self.interface
             while iface:
                 iface.setUserData('hasConcreteDescendant', True)
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -25,27 +25,35 @@ ACCESSOR_OPT =
 endif
 
 # Need this to find all our DOM source files.
 include $(topsrcdir)/dom/dom-config.mk
 
 include $(topsrcdir)/dom/webidl/WebIDL.mk
 
 binding_include_path := mozilla/dom
-binding_header_files := $(subst .webidl,Binding.h,$(webidl_files))
-binding_cpp_files := $(subst .webidl,Binding.cpp,$(webidl_files))
+all_webidl_files = $(webidl_files)
+# Set exported_binding_headers before adding the test IDL to the mix
+exported_binding_headers := $(subst .webidl,Binding.h,$(all_webidl_files))
+# Set linked_binding_cpp_files before adding the test IDL to the mix
+linked_binding_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files))
+
+all_webidl_files += $(test_webidl_files)
+
+binding_header_files := $(subst .webidl,Binding.h,$(all_webidl_files))
+binding_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files))
 
 globalgen_targets := \
   PrototypeList.h \
   RegisterBindings.h \
   RegisterBindings.cpp \
   $(NULL)
 
 CPPSRCS = \
-  $(binding_cpp_files) \
+  $(linked_binding_cpp_files) \
   $(filter %.cpp, $(globalgen_targets)) \
   BindingUtils.cpp \
   $(NULL)
 
 EXPORTS_NAMESPACES = $(binding_include_path) mozilla
 
 EXPORTS_mozilla = \
   ErrorResult.h \
@@ -54,52 +62,58 @@ EXPORTS_mozilla = \
 EXPORTS_$(binding_include_path) = \
   DOMJSClass.h \
   PrototypeList.h \
   RegisterBindings.h \
   Nullable.h \
   PrimitiveConversions.h \
   TypedArray.h \
   BindingUtils.h \
-  $(binding_header_files) \
+  $(exported_binding_headers) \
   $(NULL)
 
 LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
   -I$(topsrcdir)/js/xpconnect/wrappers
 
-TEST_DIRS += test
-
 include $(topsrcdir)/config/rules.mk
 
+# If you change bindinggen_dependencies here, change it in
+# dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
   BindingGen.py \
   Bindings.conf \
   Configuration.py \
   Codegen.py \
   ParserResults.pkl \
   $(GLOBAL_DEPS) \
   $(NULL)
 
+$(webidl_files): %: $(webidl_base)/%
+	$(INSTALL) $(IFLAGS1) $(webidl_base)/$* .
+
+$(test_webidl_files): %: $(srcdir)/test/%
+	$(INSTALL) $(IFLAGS1) $(srcdir)/test/$* .
+
 $(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
-                                     $(webidl_base)/%.webidl \
+                                     %.webidl \
                                      $(NULL)
 	PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
 	  $(PLY_INCLUDE) -I$(srcdir)/parser \
-    	  $(srcdir)/BindingGen.py $(ACCESSOR_OPT) header \
+	  $(srcdir)/BindingGen.py $(ACCESSOR_OPT) header \
 	  $(srcdir)/Bindings.conf $*Binding \
-	  $(webidl_base)/$*.webidl
+	  $*.webidl
 
 $(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
-                                    $(webidl_base)/%.webidl \
+                                    %.webidl \
                                     $(NULL)
 	PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
 	  $(PLY_INCLUDE) -I$(srcdir)/parser \
 	  $(srcdir)/BindingGen.py $(ACCESSOR_OPT) cpp \
 	  $(srcdir)/Bindings.conf $*Binding \
-	  $(webidl_base)/$*.webidl
+	  $*.webidl
 
 $(globalgen_targets): ParserResults.pkl
 
 CACHE_DIR = _cache
 
 globalgen_dependencies := \
   GlobalGen.py \
   Bindings.conf \
@@ -109,23 +123,24 @@ globalgen_dependencies := \
   $(GLOBAL_DEPS) \
   $(NULL)
 
 $(CACHE_DIR)/.done:
 	$(MKDIR) -p $(CACHE_DIR)
 	@$(TOUCH) $@
 
 ParserResults.pkl: $(globalgen_dependencies) \
-                   $(addprefix $(webidl_base)/, $(webidl_files))
+                   $(all_webidl_files)
 	PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
     $(PLY_INCLUDE) -I$(srcdir)/parser \
-    $(srcdir)/GlobalGen.py $(ACCESSOR_OPT) $(srcdir)/Bindings.conf $(webidl_base) \
+    $(srcdir)/GlobalGen.py $(ACCESSOR_OPT) $(srcdir)/Bindings.conf . \
     --cachedir=$(CACHE_DIR) \
-    $(webidl_files)
+    $(all_webidl_files)
 
 GARBAGE += \
   $(binding_header_files) \
   $(binding_cpp_files) \
+  $(all_webidl_files) \
   $(globalgen_targets) \
   ParserResults.pkl \
   webidlyacc.py \
   parser.out \
   $(NULL)
--- a/dom/bindings/test/Makefile.in
+++ b/dom/bindings/test/Makefile.in
@@ -3,20 +3,64 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH = ../../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 relativesrcdir = dom/bindings/test
 
+MODULE           = dom
+LIBRARY_NAME     = dombindings_test_s
+LIBXUL_LIBRARY   = 1
+FORCE_STATIC_LIB = 1
+# Do NOT export this library.  We don't actually want our test code
+# being added to libxul or anything.
+
 include $(DEPTH)/config/autoconf.mk
+
+# Need this to find all our DOM source files.
+include $(topsrcdir)/dom/dom-config.mk
+
+# And need this for $(test_webidl_files)
+include $(topsrcdir)/dom/webidl/WebIDL.mk
+
+# But the webidl actually lives in our parent dir
+test_webidl_files := $(addprefix ../,$(test_webidl_files))
+
+CPPSRCS := $(subst .webidl,Binding.cpp,$(test_webidl_files))
+
+LOCAL_INCLUDES += \
+  -I$(topsrcdir)/js/xpconnect/src \
+  -I$(topsrcdir)/js/xpconnect/wrappers \
+  $(NULL)
+
 include $(topsrcdir)/config/rules.mk
 
+# If you change bindinggen_dependencies here, change it in
+# dom/bindings/Makefile.in too.  But note that we include ../Makefile
+# here manually, since $(GLOBAL_DEPS) won't cover it.
+bindinggen_dependencies := \
+  ../BindingGen.py \
+  ../Bindings.conf \
+  ../Configuration.py \
+  ../Codegen.py \
+  ../ParserResults.pkl \
+  ../Makefile \
+  $(GLOBAL_DEPS) \
+  $(NULL)
+
+$(CPPSRCS): ../%Binding.cpp: $(bindinggen_dependencies) \
+                             ../%.webidl \
+                             $(NULL)
+	$(MAKE) -C .. $*Binding.h
+	$(MAKE) -C .. $*Binding.cpp
+
 _TEST_FILES = \
   test_interfaceToString.html \
   test_lookupGetter.html \
   test_InstanceOf.html \
   test_traceProtos.html \
   $(NULL)
 
+
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+#ifndef TestBindingHeader_h
+#define TestBindingHeader_h
+
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+namespace dom {
+
+class TestInterface : public nsISupports,
+		      public nsWrapperCache
+{
+public:
+  NS_DECL_ISUPPORTS
+
+  virtual nsISupports* GetParentObject();
+
+private:
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* TestBindingHeader_h */
new file mode 100644
--- /dev/null
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -0,0 +1,8 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+interface TestInterface {
+};
\ No newline at end of file
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -7,8 +7,15 @@ webidl_base = $(topsrcdir)/dom/webidl
 webidl_files = \
   Function.webidl \
   EventListener.webidl \
   EventTarget.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
   XMLHttpRequestUpload.webidl \
   $(NULL)
+
+ifdef ENABLE_TESTS
+test_webidl_files := TestCodeGen.webidl
+else
+test_webidl_files := $(NULL)
+endif
+