Allow a manifest to register contracts and cids in any order, by deferring processing of contracts until the manifest is completely parsed. This is needed for extension author sanity, and also because jar.mn packaging doesn't place registration lines in order by default.

This commit is contained in:
Benjamin Smedberg 2010-06-25 08:19:48 -04:00
Родитель 8146fde6ce
Коммит 6a6ee9e7df
4 изменённых файлов: 83 добавлений и 5 удалений

Просмотреть файл

@ -84,6 +84,8 @@ struct ManifestDirective
(nsChromeRegistry::ManifestProcessingContext& cx,
int lineno, char *const *argv,
bool platform, bool contentaccessible);
bool isContract;
};
static const ManifestDirective kParsingTable[] = {
{ "binary-component", 1, true, false, false,
@ -91,7 +93,7 @@ static const ManifestDirective kParsingTable[] = {
{ "component", 2, true, false, false,
&nsComponentManagerImpl::ManifestComponent, NULL },
{ "contract", 2, true, false, false,
&nsComponentManagerImpl::ManifestContract, NULL },
&nsComponentManagerImpl::ManifestContract, NULL, true},
{ "category", 3, true, false, false,
&nsComponentManagerImpl::ManifestCategory, NULL },
{ "content", 2, true, true, true,
@ -331,6 +333,16 @@ CheckVersionFlag(const nsString& aFlag, const nsString& aData,
return true;
}
namespace {
struct CachedDirective
{
int lineno;
char* argv[4];
};
} // anonymous namespace
void
ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
bool aChromeOnly)
@ -393,6 +405,10 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
gtk_minor_version);
#endif
// Because contracts must be registered after CIDs, we save and process them
// at the end.
nsTArray<CachedDirective> contracts;
char *token;
char *newline = buf;
PRUint32 line = 0;
@ -479,8 +495,22 @@ ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf,
(nsChromeRegistry::gChromeRegistry->*(directive->regfunc))
(chromecx, line, argv, platform, contentAccessible);
}
else if (!aChromeOnly)
(nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc))
(mgrcx, line, argv);
else if (!aChromeOnly) {
if (directive->isContract) {
CachedDirective* cd = contracts.AppendElement();
cd->lineno = line;
cd->argv[0] = argv[0];
cd->argv[1] = argv[1];
}
else
(nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc))
(mgrcx, line, argv);
}
}
for (PRInt32 i = 0; i < contracts.Length(); ++i) {
CachedDirective& d = contracts[i];
nsComponentManagerImpl::gComponentManager->ManifestContract
(mgrcx, d.lineno, d.argv);
}
}

Просмотреть файл

@ -235,6 +235,20 @@ _PlatformDeinitProfiler()
//-----------------------------------------------------------------------------
class ScopedLogging
{
public:
ScopedLogging()
{
NS_LogInit();
}
~ScopedLogging()
{
NS_LogTerm();
}
};
class ScopedXPCOM : public nsIDirectoryServiceProvider2
{
public:

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -44,6 +44,7 @@
#include "nsCOMArray.h"
#include "nsArrayEnumerator.h"
#include "nsXULAppAPI.h"
#include "nsIComponentRegistrar.h"
#define SERVICE_A_CONTRACT_ID "@mozilla.org/RegTestServiceA;1"
#define SERVICE_B_CONTRACT_ID "@mozilla.org/RegTestServiceB;1"
@ -132,6 +133,30 @@ nsresult TestRegular()
kCoreServiceA_CID, kExtServiceA_CID);
}
bool TestContractFirst()
{
nsCOMPtr<nsIComponentRegistrar> r;
NS_GetComponentRegistrar(getter_AddRefs(r));
nsCID* cid = NULL;
nsresult rv = r->ContractIDToCID("@mozilla.org/RegTestOrderC;1", &cid);
if (NS_FAILED(rv)) {
fail("RegTestOrderC: contract not registered");
return false;
}
nsCID goodcid;
goodcid.Parse("{ada15884-bb89-473c-8b50-dcfbb8447ff4}");
if (!goodcid.Equals(*cid)) {
fail("RegTestOrderC: CID doesn't match");
return false;
}
passed("RegTestOrderC");
return true;
}
static already_AddRefed<nsILocalFile>
GetRegDirectory(const char* basename, const char* dirname)
{
@ -145,6 +170,8 @@ GetRegDirectory(const char* basename, const char* dirname)
return f.forget();
}
int main(int argc, char** argv)
{
if (argc < 2)
@ -153,6 +180,7 @@ int main(int argc, char** argv)
return 1;
}
ScopedLogging logging;
const char *regPath = argv[1];
XRE_AddComponentLocation(NS_COMPONENT_LOCATION,
@ -167,5 +195,8 @@ int main(int argc, char** argv)
if (NS_FAILED(TestRegular()))
rv = 1;
if (!TestContractFirst())
rv = 1;
return rv;
}

Просмотреть файл

@ -1,2 +1,5 @@
component {56ab1cd4-ac44-4f86-8104-171f8b8f2fc7} component.js
contract @mozilla.org/RegTestServiceA;1 {56ab1cd4-ac44-4f86-8104-171f8b8f2fc7}
contract @mozilla.org/RegTestOrderC;1 {ada15884-bb89-473c-8b50-dcfbb8447ff4}
component {ada15884-bb89-473c-8b50-dcfbb8447ff4} missing.js