Bug 1524688: Part 1b - Support static JavaScript components in browser_all_files_referenced. r=mccr8
☠☠ backed out by 1a199fcf0ef6 ☠ ☠
authorKris Maglione <maglione.k@gmail.com>
Thu, 31 Jan 2019 14:24:37 -0800
changeset 520214 042a975d3971e60f1edbaa8338332c0daa596b90
parent 520213 abaf68fe399ba6871f254b32ca6660892ff09da1
child 520215 32240c1876469d81df538053257013664a9e83bb
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1524688
milestone67.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 1524688: Part 1b - Support static JavaScript components in browser_all_files_referenced. r=mccr8
browser/base/content/test/static/browser_all_files_referenced.js
xpcom/components/StaticComponents.cpp.in
xpcom/components/StaticComponents.h
xpcom/components/gen_static_components.py
xpcom/components/nsComponentManager.cpp
xpcom/components/nsIComponentManager.idl
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -638,16 +638,20 @@ add_task(async function checkAllTheFiles
     }
 
     return true;
   });
 
   // Wait for all manifest to be parsed
   await throttledMapPromises(manifestURIs, parseManifest);
 
+  for (let jsm of Components.manager.getComponentJSMs()) {
+    gReferencesFromCode.set(jsm, null);
+  }
+
   // manifest.json is a common name, it is used for WebExtension manifests
   // but also for other things.  To tell them apart, we have to actually
   // read the contents.  This will populate gExtensionRoots with all
   // embedded extension APIs, and return any manifest.json files that aren't
   // webextensions.
   let nonWebextManifests = (await Promise.all(jsonManifests.map(parseJsonManifest)))
                                          .filter(uri => !!uri);
   uris.push(...nonWebextManifests);
--- a/xpcom/components/StaticComponents.cpp.in
+++ b/xpcom/components/StaticComponents.cpp.in
@@ -4,24 +4,26 @@
  * 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/. */
 
 #include "StaticComponents.h"
 
 #include "mozilla/PerfectHash.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/StaticPtr.h"
+#include "mozilla/UniquePtr.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozJSComponentLoader.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManager.h"
 #include "nsContentUtils.h"
 #include "nsIFactory.h"
 #include "nsISupports.h"
 #include "nsString.h"
+#include "nsStringEnumerator.h"
 
 // Cleanup pollution from zipstruct.h
 #undef UNSUPPORTED
 
 // Public includes
 //# @includes@
 
 // Relative includes
@@ -63,16 +65,20 @@ static const char gStrings[] =
 
 const StaticCategory gStaticCategories[kStaticCategoryCount] = {
 //# @categories@
 };
 const StaticCategoryEntry gStaticCategoryEntries[] = {
 //# @category_entries@
 };
 
+const StringOffset gComponentJSMs[] = {
+//# @component_jsms@
+};
+
 /**
  * Returns a nsCString corresponding to the given entry in the `gStrings` string
  * table. The resulting nsCString points directly to static storage, and does
  * not incur any memory allocation overhead.
  */
 static inline nsCString GetString(const StringOffset& aOffset) {
   const char* str = &gStrings[aOffset.mOffset];
   nsCString result;
@@ -263,16 +269,30 @@ nsCString StaticCategory::Name() const {
     const nsACString& aContractID, bool aInvalid) {
   if (const ContractEntry* entry = LookupContractID(aContractID)) {
     entry->SetInvalid(aInvalid);
     return true;
   }
   return false;
 }
 
+/* static */ already_AddRefed<nsIUTF8StringEnumerator>
+StaticComponents::GetComponentJSMs() {
+  auto jsms = MakeUnique<nsTArray<nsCString>>(MOZ_ARRAY_LENGTH(gComponentJSMs));
+
+  for (const auto& entry : gComponentJSMs) {
+    jsms->AppendElement(GetString(entry));
+  }
+
+  nsCOMPtr<nsIUTF8StringEnumerator> result;
+  MOZ_ALWAYS_SUCCEEDS(NS_NewAdoptingUTF8StringEnumerator(getter_AddRefs(result),
+                                                         jsms.release()));
+  return result.forget();
+}
+
 /* static */ void StaticComponents::Shutdown() {
   CallUnloadFuncs();
 }
 
 /* static */ const nsID& Components::GetCID(ModuleID aID) {
   return gStaticModules[size_t(aID)].CID();
 }
 
--- a/xpcom/components/StaticComponents.h
+++ b/xpcom/components/StaticComponents.h
@@ -12,16 +12,17 @@
 #include "nsID.h"
 #include "nsStringFwd.h"
 #include "nscore.h"
 
 #include "mozilla/Components.h"
 #include "StaticComponentData.h"
 
 class nsIFactory;
+class nsIUTF8StringEnumerator;
 class nsISupports;
 
 namespace mozilla {
 namespace xpcom {
 
 struct ContractEntry;
 struct StaticModule;
 
@@ -203,16 +204,18 @@ class StaticComponents final {
 
   /**
    * Marks a static contract ID entry invalid (or unsets the invalid bit if
    * aInvalid is false). See `CategoryEntry::Invalid()`.
    */
   static bool InvalidateContractID(const nsACString& aContractID,
                                    bool aInvalid = true);
 
+  static already_AddRefed<nsIUTF8StringEnumerator> GetComponentJSMs();
+
   /**
    * Calls any module unload from manifests whose components have been loaded.
    */
   static void Shutdown();
 };
 
 }  // namespace xpcom
 }  // namespace mozilla
--- a/xpcom/components/gen_static_components.py
+++ b/xpcom/components/gen_static_components.py
@@ -562,16 +562,18 @@ def gen_substs(manifests):
 
         for clas in manifest['Classes']:
             modules.append(ModuleEntry(clas, init_idx))
 
     contracts = []
     contract_map = {}
     categories = defaultdict(list)
 
+    jsms = set()
+
     types = set()
 
     for mod in modules:
         headers |= set(mod.headers)
 
         for contract_id in mod.contract_ids:
             if contract_id in contract_map:
                 raise Exception('Duplicate contract ID: %s' % contract_id)
@@ -583,16 +585,19 @@ def gen_substs(manifests):
         for category, entries in mod.categories.items():
             for entry in to_list(entries):
                 categories[category].append((entry, mod.contract_id,
                                              mod.processes))
 
         if mod.type and not mod.headers:
             types.add(mod.type)
 
+        if mod.jsm:
+            jsms.add(mod.jsm)
+
     cid_phf = PerfectHash(modules, PHF_SIZE,
                           key=lambda module: module.cid.bytes)
 
     contract_phf = PerfectHash(contracts, PHF_SIZE,
                                key=lambda entry: entry.contract)
 
     substs = {}
 
@@ -603,16 +608,19 @@ def gen_substs(manifests):
 
     substs['module_count'] = len(modules)
     substs['contract_count'] = len(contracts)
 
     gen_module_funcs(substs, module_funcs)
 
     gen_includes(substs, headers)
 
+    substs['component_jsms'] = '\n'.join(' %s,' % strings.entry_to_cxx(jsm)
+                                         for jsm in sorted(jsms)) + '\n'
+
     substs['decls'] = gen_decls(types)
 
     substs['constructors'] = gen_constructors(cid_phf.entries)
 
     substs['component_getters'] = gen_getters(cid_phf.entries)
 
     substs['module_cid_table'] = cid_phf.cxx_codegen(
         name='ModuleByCID',
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -2007,16 +2007,24 @@ nsComponentManagerImpl::RemoveBootstrapp
   // Remove reference.
   nsComponentManagerImpl::sModuleLocations->RemoveElement(
       elem, ComponentLocationComparator());
 
   rv = cr->CheckForNewChrome();
   return rv;
 }
 
+
+NS_IMETHODIMP
+nsComponentManagerImpl::GetComponentJSMs(nsIUTF8StringEnumerator** aJSMs) {
+  nsCOMPtr<nsIUTF8StringEnumerator> result = StaticComponents::GetComponentJSMs();
+  result.forget(aJSMs);
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsComponentManagerImpl::GetManifestLocations(nsIArray** aLocations) {
   NS_ENSURE_ARG_POINTER(aLocations);
   *aLocations = nullptr;
 
   if (!sModuleLocations) {
     return NS_ERROR_NOT_INITIALIZED;
   }
--- a/xpcom/components/nsIComponentManager.idl
+++ b/xpcom/components/nsIComponentManager.idl
@@ -7,16 +7,17 @@
  * The nsIComponentManager interface.
  */
 
 #include "nsISupports.idl"
 
 interface nsIFile;
 interface nsIFactory;
 interface nsIArray;
+interface nsIUTF8StringEnumerator;
 
 [scriptable, uuid(d604ffc3-1ba3-4f6c-b65f-1ed4199364c3)]
 interface nsIComponentManager : nsISupports
 {
     /**
      * getClassObject
      *
      * Returns the factory object that can be used to create instances of
@@ -91,16 +92,22 @@ interface nsIComponentManager : nsISuppo
     void removeBootstrappedManifestLocation(in nsIFile aLocation);
 
     /**
      * getManifestLocations
      *
      * Get an array of nsIURIs of all registered and builtin manifest locations.
      */
     nsIArray getManifestLocations();
+
+    /**
+     * Returns a list of JSM URLs which are used to create components. This
+     * should only be used in automation.
+     */
+    nsIUTF8StringEnumerator getComponentJSMs();
 };
 
 
 %{ C++
 #ifdef MOZILLA_INTERNAL_API
 #include "nsComponentManagerUtils.h"
 #endif
 %} C++