bug 523272: allow protocols to reference great*grandchild actors

This commit is contained in:
Chris Jones 2009-10-19 21:12:25 -05:00
Родитель 4a5d5780c1
Коммит f72539f841
11 изменённых файлов: 337 добавлений и 4 удалений

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

@ -96,7 +96,8 @@ class Visitor:
trans.accept(self) trans.accept(self)
def visitTransition(self, t): def visitTransition(self, t):
t.toState.accept(self) for toState in t.toStates:
toState.accept(self)
def visitState(self, s): def visitState(self, s):
pass pass

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

@ -1931,6 +1931,58 @@ def _generateCxxUnionStuff(ud):
##----------------------------------------------------------------------------- ##-----------------------------------------------------------------------------
class _FindFriends(ipdl.ast.Visitor):
def __init__(self):
self.mytype = None # ProtocolType
self.vtype = None # ProtocolType
self.friends = set() # set<ProtocolType>
self.visited = set() # set<ProtocolType>
def findFriends(self, ptype):
self.mytype = ptype
self.walkUpTheProtocolTree(ptype)
self.walkDownTheProtocolTree(ptype)
return self.friends
# TODO could make this into a _iterProtocolTreeHelper ...
def walkUpTheProtocolTree(self, ptype):
if not ptype.isManaged():
return
mtype = ptype.manager
self.visit(mtype)
self.walkUpTheProtocolTree(mtype)
def walkDownTheProtocolTree(self, ptype):
if not ptype.isManager():
return
for mtype in ptype.manages:
self.visit(mtype)
self.walkDownTheProtocolTree(mtype)
def visit(self, ptype):
if ptype in self.visited:
return
self.visited.add(ptype)
savedptype = self.vtype
self.vtype = ptype
ptype._p.accept(self)
self.vtype = savedptype
def visitMessageDecl(self, md):
for it in self.iterActorParams(md):
if it.protocol == self.mytype:
self.friends.add(self.vtype)
def iterActorParams(self, md):
for param in md.inParams:
for actor in ipdl.type.iteractortypes(param.type):
yield actor
for ret in md.outParams:
for actor in ipdl.type.iteractortypes(ret.type):
yield actor
class _Result: class _Result:
Type = Type('Result') Type = Type('Result')
@ -2033,14 +2085,18 @@ class _GenerateProtocolActorHeader(ipdl.ast.Visitor):
inherits.append(Inherit(p.managerCxxType())) inherits.append(Inherit(p.managerCxxType()))
self.cls = Class(self.clsname, inherits=inherits, abstract=True) self.cls = Class(self.clsname, inherits=inherits, abstract=True)
friends = _FindFriends().findFriends(p.decl.type)
if p.decl.type.isManaged(): if p.decl.type.isManaged():
friends.add(p.decl.type.manager)
for friend in friends:
self.file.addthings([ self.file.addthings([
Whitespace.NL, Whitespace.NL,
_makeForwardDecl(p.decl.type.manager, self.prettyside), _makeForwardDecl(friend, self.prettyside),
Whitespace.NL Whitespace.NL
]) ])
self.cls.addstmts([ self.cls.addstmts([
FriendClassDecl(_actorName(p.decl.type.manager.fullname(), FriendClassDecl(_actorName(friend.fullname(),
self.prettyside)), self.prettyside)),
Whitespace.NL ]) Whitespace.NL ])

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

@ -499,6 +499,10 @@ class GatherDecls(TcheckVisitor):
shortname=p.name, shortname=p.name,
fullname=fullname) fullname=fullname)
# XXX ugh, this sucks. but we need this information to compute
# what friend decls we need in generated C++
p.decl.type._p = p
# make sure we have decls for all dependent protocols # make sure we have decls for all dependent protocols
for pinc in tu.protocolIncludes: for pinc in tu.protocolIncludes:
pinc.accept(self) pinc.accept(self)

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

@ -61,6 +61,7 @@ IPDLTESTS = \
TestSanity \ TestSanity \
TestLatency \ TestLatency \
TestManyChildAllocs \ TestManyChildAllocs \
TestDesc \
TestArrays \ TestArrays \
$(NULL) $(NULL)

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

@ -0,0 +1,28 @@
include protocol "PTestDescSub.ipdl";
include protocol "PTestDescSubsub.ipdl";
namespace mozilla {
namespace _ipdltest {
protocol PTestDesc {
manages PTestDescSub;
child:
PTestDescSub();
~PTestDescSub();
Test(PTestDescSubsub a);
parent:
Ok(PTestDescSubsub a);
state START:
send Test goto ACK;
state ACK:
recv Ok goto ACK;
// delete
};
}
}

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

@ -0,0 +1,17 @@
include protocol "PTestDesc.ipdl";
include protocol "PTestDescSubsub.ipdl";
namespace mozilla {
namespace _ipdltest {
protocol PTestDescSub {
manager PTestDesc;
manages PTestDescSubsub;
child:
PTestDescSubsub();
~PTestDescSubsub();
};
}
}

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

@ -0,0 +1,13 @@
include protocol "PTestDescSub.ipdl";
namespace mozilla {
namespace _ipdltest {
protocol PTestDescSubsub {
manager PTestDescSub;
// empty
};
}
}

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

@ -0,0 +1,108 @@
#include "TestDesc.h"
#include "nsIAppShell.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h" // do_GetService()
#include "nsWidgetsCID.h" // NS_APPSHELL_CID
#include "IPDLUnitTests.h" // fail etc.
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
// parent
void
TestDescParent::Main()
{
PTestDescSubParent* p = SendPTestDescSubConstructor();
if (!p)
fail("can't allocate Sub");
PTestDescSubsubParent* pp = p->SendPTestDescSubsubConstructor();
if (!pp)
fail("can't allocate Subsub");
if (!SendTest(pp))
fail("can't send Subsub");
}
bool
TestDescParent::RecvOk(PTestDescSubsubParent* a)
{
if (!a)
fail("didn't receive Subsub");
passed("ok");
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
nsCOMPtr<nsIAppShell> appShell (do_GetService(kAppShellCID));
appShell->Exit();
return true;
}
PTestDescSubParent*
TestDescParent::AllocPTestDescSub() {
return new TestDescSubParent();
}
bool
TestDescParent::DeallocPTestDescSub(PTestDescSubParent* actor)
{
delete actor;
return true;
}
PTestDescSubsubParent*
TestDescSubParent::AllocPTestDescSubsub()
{
return new TestDescSubsubParent();
}
bool
TestDescSubParent::DeallocPTestDescSubsub(PTestDescSubsubParent* actor)
{
delete actor;
return true;
}
//-----------------------------------------------------------------------------
// child
bool
TestDescChild::RecvTest(PTestDescSubsubChild* a)
{
if (!a)
fail("didn't receive Subsub");
if (!SendOk(a))
fail("couldn't send Ok()");
return true;
}
PTestDescSubChild*
TestDescChild::AllocPTestDescSub() {
return new TestDescSubChild();
}
bool
TestDescChild::DeallocPTestDescSub(PTestDescSubChild* actor)
{
delete actor;
return true;
}
PTestDescSubsubChild*
TestDescSubChild::AllocPTestDescSubsub()
{
return new TestDescSubsubChild();
}
bool
TestDescSubChild::DeallocPTestDescSubsub(PTestDescSubsubChild* actor)
{
delete actor;
return true;
}
} // namespace _ipdltest
} // namespace mozilla

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

@ -0,0 +1,102 @@
#ifndef mozilla_ipdltest_TestDesc_h
#define mozilla_ipdltest_TestDesc_h
#include "mozilla/_ipdltest/PTestDescParent.h"
#include "mozilla/_ipdltest/PTestDescChild.h"
#include "mozilla/_ipdltest/PTestDescSubParent.h"
#include "mozilla/_ipdltest/PTestDescSubChild.h"
#include "mozilla/_ipdltest/PTestDescSubsubParent.h"
#include "mozilla/_ipdltest/PTestDescSubsubChild.h"
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
// Top-level
//
class TestDescParent :
public PTestDescParent
{
public:
TestDescParent() { }
virtual ~TestDescParent() { }
void Main();
virtual bool RecvOk(PTestDescSubsubParent* a);
protected:
virtual PTestDescSubParent* AllocPTestDescSub();
virtual bool DeallocPTestDescSub(PTestDescSubParent* actor);
};
class TestDescChild :
public PTestDescChild
{
public:
TestDescChild() { }
virtual ~TestDescChild() { }
protected:
virtual PTestDescSubChild* AllocPTestDescSub();
virtual bool DeallocPTestDescSub(PTestDescSubChild* actor);
virtual bool RecvTest(PTestDescSubsubChild* a);
};
//-----------------------------------------------------------------------------
// First descendent
//
class TestDescSubParent :
public PTestDescSubParent
{
public:
TestDescSubParent() { }
virtual ~TestDescSubParent() { }
protected:
virtual PTestDescSubsubParent* AllocPTestDescSubsub();
virtual bool DeallocPTestDescSubsub(PTestDescSubsubParent* actor);
};
class TestDescSubChild :
public PTestDescSubChild
{
public:
TestDescSubChild() { }
virtual ~TestDescSubChild() { }
protected:
virtual PTestDescSubsubChild* AllocPTestDescSubsub();
virtual bool DeallocPTestDescSubsub(PTestDescSubsubChild* actor);
};
//-----------------------------------------------------------------------------
// Grand-descendent
//
class TestDescSubsubParent :
public PTestDescSubsubParent
{
public:
TestDescSubsubParent() { }
virtual ~TestDescSubsubParent() { }
};
class TestDescSubsubChild :
public PTestDescSubsubChild
{
public:
TestDescSubsubChild() { }
virtual ~TestDescSubsubChild() { }
};
}
}
#endif // ifndef mozilla_ipdltest_TestDesc_h

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

@ -9,7 +9,7 @@
#include "IPDLUnitTests.h" // fail etc. #include "IPDLUnitTests.h" // fail etc.
#define NR_TRIALS 100000 #define NR_TRIALS 10000
namespace mozilla { namespace mozilla {
namespace _ipdltest { namespace _ipdltest {

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

@ -1,6 +1,9 @@
IPDLSRCS = \ IPDLSRCS = \
PTestArrays.ipdl \ PTestArrays.ipdl \
PTestArraysSub.ipdl \ PTestArraysSub.ipdl \
PTestDesc.ipdl \
PTestDescSub.ipdl \
PTestDescSubsub.ipdl \
PTestLatency.ipdl \ PTestLatency.ipdl \
PTestManyChildAllocs.ipdl \ PTestManyChildAllocs.ipdl \
PTestManyChildAllocsSub.ipdl \ PTestManyChildAllocsSub.ipdl \