mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
add parsing and type-checking of protocol state machines in preparation for codegen of dynamic FSM checker. fix a couple of bugs here and there.
This commit is contained in:
parent
d3e2234d01
commit
7929ffa13d
@ -16,9 +16,12 @@ namespace IFrameEmbeddingProtocol {
|
||||
|
||||
|
||||
enum State {
|
||||
StateStart = 0,
|
||||
StateError,
|
||||
StateLast
|
||||
};
|
||||
|
||||
enum IFrameEmbeddingProtocolMsgType {
|
||||
enum MessageType {
|
||||
IFrameEmbeddingProtocolStart = IFrameEmbeddingProtocolMsgStart << 12,
|
||||
IFrameEmbeddingProtocolPreStart = (IFrameEmbeddingProtocolMsgStart << 12) - 1,
|
||||
Msg_init__ID,
|
||||
@ -29,6 +32,7 @@ enum IFrameEmbeddingProtocolMsgType {
|
||||
Reply_move__ID,
|
||||
IFrameEmbeddingProtocolEnd
|
||||
};
|
||||
|
||||
class Msg_init :
|
||||
public IPC::Message
|
||||
{
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
if (!(IFrameEmbeddingProtocol::Msg_init::Read(&(msg), &(parentWidget)))) {
|
||||
return MsgPayloadError;
|
||||
}
|
||||
if (Answerinit(parentWidget)) {
|
||||
if (NS_FAILED(Answerinit(parentWidget))) {
|
||||
return MsgValueError;
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ public:
|
||||
if (!(IFrameEmbeddingProtocol::Msg_loadURL::Read(&(msg), &(uri)))) {
|
||||
return MsgPayloadError;
|
||||
}
|
||||
if (AnswerloadURL(uri)) {
|
||||
if (NS_FAILED(AnswerloadURL(uri))) {
|
||||
return MsgValueError;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ public:
|
||||
if (!(IFrameEmbeddingProtocol::Msg_move::Read(&(msg), &(x), &(y), &(width), &(height)))) {
|
||||
return MsgPayloadError;
|
||||
}
|
||||
if (Answermove(x, y, width, height)) {
|
||||
if (NS_FAILED(Answermove(x, y, width, height))) {
|
||||
return MsgValueError;
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,12 @@ namespace NPAPIProtocol {
|
||||
|
||||
|
||||
enum State {
|
||||
StateStart = 0,
|
||||
StateError,
|
||||
StateLast
|
||||
};
|
||||
|
||||
enum NPAPIProtocolMsgType {
|
||||
enum MessageType {
|
||||
NPAPIProtocolStart = NPAPIProtocolMsgStart << 12,
|
||||
NPAPIProtocolPreStart = (NPAPIProtocolMsgStart << 12) - 1,
|
||||
Msg_NP_Initialize__ID,
|
||||
@ -33,6 +36,7 @@ enum NPAPIProtocolMsgType {
|
||||
Reply_NPPDestructor__ID,
|
||||
NPAPIProtocolEnd
|
||||
};
|
||||
|
||||
class Msg_NP_Initialize :
|
||||
public IPC::Message
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ public:
|
||||
if (!(NPAPIProtocol::Msg_NP_Initialize::Read(&(msg)))) {
|
||||
return MsgPayloadError;
|
||||
}
|
||||
if (AnswerNP_Initialize(&(rv))) {
|
||||
if (NS_FAILED(AnswerNP_Initialize(&(rv)))) {
|
||||
return MsgValueError;
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ public:
|
||||
if (!(__a)) {
|
||||
return MsgValueError;
|
||||
}
|
||||
if (NPPDestructor(__a, &(rv))) {
|
||||
if (NS_FAILED(NPPDestructor(__a, &(rv)))) {
|
||||
return MsgValueError;
|
||||
}
|
||||
Unregister(__ah.mChildId);
|
||||
|
@ -20,9 +20,12 @@ namespace NPPProtocol {
|
||||
|
||||
|
||||
enum State {
|
||||
StateStart = 0,
|
||||
StateError,
|
||||
StateLast
|
||||
};
|
||||
|
||||
enum NPPProtocolMsgType {
|
||||
enum MessageType {
|
||||
NPPProtocolStart = NPPProtocolMsgStart << 12,
|
||||
NPPProtocolPreStart = (NPPProtocolMsgStart << 12) - 1,
|
||||
Msg_NPP_SetWindow__ID,
|
||||
@ -33,6 +36,7 @@ enum NPPProtocolMsgType {
|
||||
Reply_NPN_GetValue__ID,
|
||||
NPPProtocolEnd
|
||||
};
|
||||
|
||||
class Msg_NPP_SetWindow :
|
||||
public IPC::Message
|
||||
{
|
||||
|
@ -94,7 +94,7 @@ public:
|
||||
if (!(NPPProtocol::Msg_NPP_SetWindow::Read(&(msg), &(window)))) {
|
||||
return MsgPayloadError;
|
||||
}
|
||||
if (AnswerNPP_SetWindow(window, &(rv))) {
|
||||
if (NS_FAILED(AnswerNPP_SetWindow(window, &(rv)))) {
|
||||
return MsgValueError;
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ public:
|
||||
if (!(NPPProtocol::Msg_NPP_GetValue::Read(&(msg), &(key)))) {
|
||||
return MsgPayloadError;
|
||||
}
|
||||
if (AnswerNPP_GetValue(key, &(value))) {
|
||||
if (NS_FAILED(AnswerNPP_GetValue(key, &(value)))) {
|
||||
return MsgValueError;
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ public:
|
||||
if (!(NPPProtocol::Msg_NPN_GetValue::Read(&(msg), &(key)))) {
|
||||
return MsgPayloadError;
|
||||
}
|
||||
if (AnswerNPN_GetValue(key, &(value))) {
|
||||
if (NS_FAILED(AnswerNPN_GetValue(key, &(value)))) {
|
||||
return MsgValueError;
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,17 @@ class Visitor:
|
||||
for outParam in md.outParams:
|
||||
outParam.accept(self)
|
||||
|
||||
def visitTransitionStmt(self, ts):
|
||||
ts.state.accept(self)
|
||||
for trans in ts.transitions:
|
||||
trans.accept(self)
|
||||
|
||||
def visitTransition(self, t):
|
||||
t.toState.accept(self)
|
||||
|
||||
def visitState(self, s):
|
||||
pass
|
||||
|
||||
def visitParam(self, decl):
|
||||
pass
|
||||
|
||||
@ -151,31 +162,57 @@ class UsingStmt(Node):
|
||||
def __init__(self, loc, cxxTypeSpec):
|
||||
Node.__init__(self, loc)
|
||||
self.type = cxxTypeSpec
|
||||
|
||||
|
||||
# "singletons"
|
||||
class ASYNC:
|
||||
pretty = 'Async'
|
||||
pretty = 'async'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
@classmethod
|
||||
def __str__(cls): return cls.pretty
|
||||
class RPC:
|
||||
pretty = 'Rpc'
|
||||
pretty = 'rpc'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
@classmethod
|
||||
def __str__(cls): return cls.pretty
|
||||
class SYNC:
|
||||
pretty = 'Sync'
|
||||
pretty = 'sync'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
@classmethod
|
||||
def __str__(cls): return cls.pretty
|
||||
|
||||
class INOUT:
|
||||
pretty = 'InOut'
|
||||
pretty = 'inout'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
@classmethod
|
||||
def __str__(cls): return cls.pretty
|
||||
class IN:
|
||||
pretty = 'in'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
@classmethod
|
||||
def __str__(cls): return cls.pretty
|
||||
@staticmethod
|
||||
def pretty(ss): return _prettyTable['In'][ss.pretty]
|
||||
def prettySS(cls, ss): return _prettyTable['in'][ss.pretty]
|
||||
class OUT:
|
||||
pretty = 'out'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
@classmethod
|
||||
def __str__(cls): return cls.pretty
|
||||
@staticmethod
|
||||
def pretty(ss): return _prettyTable['Out'][ss.pretty]
|
||||
def pretty(ss): return _prettyTable['out'][ss.pretty]
|
||||
|
||||
_prettyTable = {
|
||||
'In' : { 'Async': 'AsyncRecv',
|
||||
'Sync': 'SyncRecv',
|
||||
'Rpc': 'RpcAnswer' },
|
||||
'Out' : { 'Async': 'AsyncSend',
|
||||
'Sync': 'SyncSend',
|
||||
'Rpc': 'RpcCall' }
|
||||
IN : { 'async': 'AsyncRecv',
|
||||
'sync': 'SyncRecv',
|
||||
'rpc': 'RpcAnswer' },
|
||||
OUT : { 'async': 'AsyncSend',
|
||||
'sync': 'SyncSend',
|
||||
'rpc': 'RpcCall' }
|
||||
# inout doesn't make sense here
|
||||
}
|
||||
|
||||
@ -235,6 +272,45 @@ class MessageDecl(Node):
|
||||
def hasReply(self):
|
||||
return self.sendSemantics is SYNC or self.sendSemantics is RPC
|
||||
|
||||
class TransitionStmt(Node):
|
||||
def __init__(self, loc, state, transitions):
|
||||
Node.__init__(self, loc)
|
||||
self.state = state
|
||||
self.transitions = transitions
|
||||
|
||||
class Transition(Node):
|
||||
def __init__(self, loc, trigger, msg, toState):
|
||||
Node.__init__(self, loc)
|
||||
self.trigger = trigger
|
||||
self.msg = msg
|
||||
self.toState = toState
|
||||
|
||||
@staticmethod
|
||||
def nameToTrigger(name):
|
||||
return { 'send': SEND, 'recv': RECV, 'call': CALL, 'answer': ANSWER }[name]
|
||||
|
||||
class SEND:
|
||||
pretty = 'send'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
class RECV:
|
||||
pretty = 'recv'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
class CALL:
|
||||
pretty = 'call'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
class ANSWER:
|
||||
pretty = 'answer'
|
||||
@classmethod
|
||||
def __hash__(cls): return hash(cls.pretty)
|
||||
|
||||
class State(Node):
|
||||
def __init__(self, loc, name):
|
||||
Node.__init__(self, loc)
|
||||
self.name = name
|
||||
|
||||
class Param(Node):
|
||||
def __init__(self, loc, typespec, name):
|
||||
Node.__init__(self, loc)
|
||||
|
@ -97,7 +97,6 @@ class GenerateProtocolHeader(Visitor):
|
||||
for tdef in self.typedefs:
|
||||
scope.addstmt(tdef)
|
||||
|
||||
|
||||
def visitTranslationUnit(self, tu):
|
||||
f = self.file
|
||||
|
||||
@ -160,20 +159,30 @@ class GenerateProtocolHeader(Visitor):
|
||||
ns.addstmt(cxx.Whitespace.NL)
|
||||
ns.addstmt(cxx.Whitespace.NL)
|
||||
|
||||
# state information
|
||||
stateenum = cxx.TypeEnum('State')
|
||||
for ts in p.transitionStmts:
|
||||
ts.accept(self)
|
||||
stateenum.addId(ts.state.decl._cxxname)
|
||||
if len(p.transitionStmts):
|
||||
startstate = p.transitionStmts[0].state.decl._cxxname
|
||||
else:
|
||||
startstate = '0'
|
||||
stateenum.addId('StateStart', startstate)
|
||||
stateenum.addId('StateError')
|
||||
stateenum.addId('StateLast')
|
||||
|
||||
ns.addstmt(cxx.StmtDecl(cxx.Decl(stateenum, '')))
|
||||
ns.addstmt(cxx.Whitespace.NL)
|
||||
|
||||
# previsit the messages and stash away some common info used
|
||||
# several times later
|
||||
for md in p.messageDecls:
|
||||
md.accept(self)
|
||||
|
||||
# TODO
|
||||
for ts in p.transitionStmts:
|
||||
ts.accept(self)
|
||||
ns.addstmt(cxx.StmtDecl(cxx.Decl(cxx.TypeEnum('State'), '')))
|
||||
ns.addstmt(cxx.Whitespace.NL)
|
||||
|
||||
# spit out message type enum and classes
|
||||
msgstart = self.pname +'MsgStart << 12'
|
||||
msgenum = cxx.TypeEnum(self.pname +'MsgType')
|
||||
msgenum = cxx.TypeEnum('MessageType')
|
||||
msgenum.addId(self.pname +'Start', msgstart)
|
||||
msgenum.addId(self.pname +'PreStart', '('+ msgstart +') - 1')
|
||||
|
||||
@ -184,6 +193,7 @@ class GenerateProtocolHeader(Visitor):
|
||||
|
||||
msgenum.addId(self.pname +'End')
|
||||
ns.addstmt(cxx.StmtDecl(cxx.Decl(msgenum, '')))
|
||||
ns.addstmt(cxx.Whitespace.NL)
|
||||
|
||||
for md in p.messageDecls:
|
||||
ns.addstmt(generateMessageClass(md, self.injectTypedefs))
|
||||
@ -232,6 +242,10 @@ class GenerateProtocolHeader(Visitor):
|
||||
md._cxx.nsreplyid = '%s::%s'% (self.pname, md._cxx.replyid)
|
||||
|
||||
|
||||
def visitTransitionStmt(self, ts):
|
||||
ts.state.decl._cxxname = 'State_%s__ID'% (ts.state.decl.progname)
|
||||
|
||||
|
||||
def generateMsgClass(md, clsname, params, typedefInjector):
|
||||
cls = cxx.Class(name=clsname,
|
||||
inherits=[ cxx.Inherit('IPC::Message') ])
|
||||
@ -334,12 +348,11 @@ def generateReplyClass(md, typedefInjector):
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
_channelTable = {
|
||||
'Async': [ 'mozilla', 'ipc', 'AsyncChannel' ],
|
||||
'Sync': [ 'mozilla', 'ipc', 'SyncChannel' ],
|
||||
'Rpc': [ 'mozilla', 'ipc', 'RPCChannel' ]
|
||||
ASYNC: [ 'mozilla', 'ipc', 'AsyncChannel' ],
|
||||
SYNC: [ 'mozilla', 'ipc', 'SyncChannel' ],
|
||||
RPC: [ 'mozilla', 'ipc', 'RPCChannel' ]
|
||||
}
|
||||
|
||||
|
||||
class GenerateProtocolActorHeader(Visitor):
|
||||
def __init__(self, myside, otherside):
|
||||
self.myside = myside # "Parent" or "Child"
|
||||
@ -396,7 +409,7 @@ class GenerateProtocolActorHeader(Visitor):
|
||||
if p.decl.type.isManager():
|
||||
self.file.addthing(cxx.CppDirective('include', '"base/id_map.h"'))
|
||||
|
||||
channel = _channelTable[p.decl.type.sendSemantics.pretty]
|
||||
channel = _channelTable[p.decl.type.sendSemantics]
|
||||
channelname = '::'.join(channel)
|
||||
channelfile = '/'.join(channel) +'.h'
|
||||
if p.decl.type.isToplevel():
|
||||
|
@ -148,7 +148,7 @@ tokens = [
|
||||
|
||||
t_COLONCOLON = '::'
|
||||
|
||||
literals = '(){}[];,~'
|
||||
literals = '(){}[];:,~'
|
||||
t_ignore = ' \f\t\v'
|
||||
|
||||
def t_linecomment(t):
|
||||
@ -175,7 +175,7 @@ def t_STRING(t):
|
||||
|
||||
def t_error(t):
|
||||
includeStackStr = Parser.includeStackString()
|
||||
raise Exception, '%s%s: lexically invalid characters %s'% (
|
||||
raise Exception, '%s%s: error: lexically invalid characters %s'% (
|
||||
includeStackStr, Loc(Parser.current.filename, t.lineno), str(t))
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
@ -319,10 +319,49 @@ def p_MessageOutParams(p):
|
||||
else:
|
||||
p[0] = p[3]
|
||||
|
||||
##--------------------
|
||||
## State machine
|
||||
|
||||
def p_TransitionStmts(p):
|
||||
"""TransitionStmts : """
|
||||
# FIXME/cjones: impl
|
||||
p[0] = [ ]
|
||||
"""TransitionStmts : TransitionStmts TransitionStmt
|
||||
| TransitionStmt
|
||||
| """
|
||||
if 3 == len(p):
|
||||
p[1].append(p[2])
|
||||
p[0] = p[1]
|
||||
elif 2 == len(p):
|
||||
p[0] = [ p[1] ]
|
||||
else:
|
||||
p[0] = [ ]
|
||||
|
||||
def p_TransitionStmt(p):
|
||||
"""TransitionStmt : State ':' Transitions"""
|
||||
p[0] = TransitionStmt(locFromTok(p, 1), p[1], p[3])
|
||||
|
||||
def p_Transitions(p):
|
||||
"""Transitions : Transitions Transition
|
||||
| Transition"""
|
||||
if 3 == len(p):
|
||||
p[1].append(p[2])
|
||||
p[0] = p[1]
|
||||
else:
|
||||
p[0] = [ p[1] ]
|
||||
|
||||
def p_Transition(p):
|
||||
"""Transition : Trigger MessageId GOTO State ';'"""
|
||||
loc, trigger = p[1]
|
||||
p[0] = Transition(loc, trigger, p[2], p[4])
|
||||
|
||||
def p_Trigger(p):
|
||||
"""Trigger : SEND
|
||||
| RECV
|
||||
| CALL
|
||||
| ANSWER"""
|
||||
p[0] = [ locFromTok(p, 1), Transition.nameToTrigger(p[1]) ]
|
||||
|
||||
def p_State(p):
|
||||
"""State : ID"""
|
||||
p[0] = State(locFromTok(p, 1), p[1])
|
||||
|
||||
##--------------------
|
||||
## Minor stuff
|
||||
@ -394,5 +433,5 @@ def p_QualifiedID(p):
|
||||
|
||||
def p_error(t):
|
||||
includeStackStr = Parser.includeStackString()
|
||||
raise Exception, '%s%s: syntax error near "%s"'% (
|
||||
raise Exception, '%s%s: error: bad syntax near "%s"'% (
|
||||
includeStackStr, Loc(Parser.current.filename, t.lineno), t.value)
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
import sys
|
||||
|
||||
from ipdl.ast import CxxInclude, Decl, Loc, QualifiedId, TypeSpec, UsingStmt, Visitor, ASYNC, SYNC, RPC, IN, OUT, INOUT
|
||||
from ipdl.ast import CxxInclude, Decl, Loc, QualifiedId, TypeSpec, UsingStmt, Visitor, ASYNC, SYNC, RPC, IN, OUT, INOUT, ANSWER, CALL, RECV, SEND
|
||||
import ipdl.builtin as builtin
|
||||
|
||||
class Type:
|
||||
@ -114,6 +114,8 @@ class GeneratedCxxType(CxxType):
|
||||
class IPDLType(Type):
|
||||
def isIPDL(self): return True
|
||||
def isVisible(self): return True
|
||||
def isState(self): return False
|
||||
def isMessage(self): return False
|
||||
def isProtocol(self): return False
|
||||
|
||||
def isAsync(self): return self.sendSemantics is ASYNC
|
||||
@ -130,6 +132,10 @@ class IPDLType(Type):
|
||||
return (o.isAsync() and not self.isAsync()
|
||||
or o.isSync() and self.isRpc())
|
||||
|
||||
class StateType(IPDLType):
|
||||
def __init__(self): pass
|
||||
def isState(self): return True
|
||||
|
||||
class MessageType(IPDLType):
|
||||
def __init__(self, sendSemantics, direction,
|
||||
ctor=False, dtor=False, cdtype=None):
|
||||
@ -319,11 +325,11 @@ class GatherDecls(Visitor):
|
||||
|
||||
# bit of a hack here --- we want the builtin |using|
|
||||
# statements to be added to the symbol table before anything
|
||||
# else, but we also want them in the top-level translation
|
||||
# unit's list of using stmts so that we can use them later
|
||||
# down the pipe. so we add them to the symbol table before
|
||||
# anything else, and prepend them to the top-level TU after
|
||||
# it's visited all its |using| decls
|
||||
# else, but we also want them in the translation units' list
|
||||
# of using stmts so that we can use them later down the pipe.
|
||||
# so we add them to the symbol table before anything else, and
|
||||
# prepend them to the TUs after visiting all their |using|
|
||||
# decls
|
||||
if 1 == self.depth:
|
||||
for using in self.builtinUsing:
|
||||
udecl = Decl(using.loc)
|
||||
@ -368,8 +374,7 @@ class GatherDecls(Visitor):
|
||||
using.accept(self)
|
||||
|
||||
# (see long comment above)
|
||||
if 1 == self.depth:
|
||||
tu.using = self.builtinUsing + tu.using
|
||||
tu.using = self.builtinUsing + tu.using
|
||||
|
||||
# grab symbols in the protocol itself
|
||||
p.accept(self)
|
||||
@ -423,6 +428,15 @@ class GatherDecls(Visitor):
|
||||
"constructor and destructor declarations are required for managed protocol `%s' (managed by protocol `%s')",
|
||||
mgdname, p.name))
|
||||
|
||||
# declare each state before decorating their mention
|
||||
for trans in p.transitionStmts:
|
||||
sdecl = Decl(trans.state.loc)
|
||||
sdecl.progname = trans.state.name
|
||||
sdecl.type = StateType()
|
||||
|
||||
self.symtab.declare(sdecl)
|
||||
trans.state.decl = sdecl
|
||||
|
||||
for trans in p.transitionStmts:
|
||||
trans.accept(self)
|
||||
|
||||
@ -595,6 +609,38 @@ class GatherDecls(Visitor):
|
||||
md.protocolDecl = self.currentProtocolDecl
|
||||
|
||||
|
||||
def visitTransition(self, t):
|
||||
loc = t.loc
|
||||
|
||||
sname = t.toState.name
|
||||
sdecl = self.symtab.lookup(sname)
|
||||
if sdecl is None:
|
||||
self.errors.append(
|
||||
errormsg(loc, "state `%s' has not been declared", sname))
|
||||
elif not sdecl.type.isState():
|
||||
self.errors.append(
|
||||
errormsg(
|
||||
loc,
|
||||
"`%s' should have state type, but instead has type `%s'",
|
||||
sname, sdecl.type.typename()))
|
||||
else:
|
||||
t.toState.decl = sdecl
|
||||
|
||||
mname = t.msg
|
||||
mdecl = self.symtab.lookup(mname)
|
||||
if mdecl is None:
|
||||
self.errors.append(
|
||||
errormsg(loc, "message `%s' has not been declared", mname))
|
||||
elif not mdecl.type.isMessage():
|
||||
self.errors.append(
|
||||
errormsg(
|
||||
loc,
|
||||
"`%s' should have message type, but instead has type `%s'",
|
||||
mname, mdecl.type.typename()))
|
||||
else:
|
||||
t.msg = mdecl
|
||||
|
||||
|
||||
class CheckTypes(Visitor):
|
||||
def __init__(self, symtab, errors):
|
||||
self.symtab = symtab
|
||||
@ -693,3 +739,25 @@ class CheckTypes(Visitor):
|
||||
"ctor/dtor for protocol `%s', which is not managed by protocol `%s'",
|
||||
mname[:-len('constructor')],
|
||||
pname))
|
||||
|
||||
|
||||
def visitTransition(self, t):
|
||||
_YNC = [ ASYNC, SYNC ]
|
||||
|
||||
loc = t.loc
|
||||
impliedDirection, impliedSems = {
|
||||
SEND: [ OUT, _YNC ], RECV: [ IN, _YNC ],
|
||||
CALL: [ OUT, RPC ], ANSWER: [ IN, RPC ]
|
||||
} [t.trigger]
|
||||
|
||||
if (OUT is impliedDirection and t.msg.type.isIn()
|
||||
or IN is impliedDirection and t.msg.type.isOut()
|
||||
or _YNC is impliedSems and t.msg.type.isRpc()
|
||||
or RPC is impliedSems and (not t.msg.type.isRpc())):
|
||||
mtype = t.msg.type
|
||||
|
||||
self.errors.append(errormsg(
|
||||
loc, "%s %s message `%s' is not `%s'd",
|
||||
mtype.sendSemantics.pretty, mtype.direction.pretty,
|
||||
t.msg.progname,
|
||||
trigger))
|
||||
|
Loading…
Reference in New Issue
Block a user