mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
add real front-end support for multiple start states in IPDL
This commit is contained in:
parent
3480e9a0e0
commit
809d7382e0
@ -226,6 +226,7 @@ class Protocol(Node):
|
|||||||
self.managesStmts = [ ]
|
self.managesStmts = [ ]
|
||||||
self.messageDecls = [ ]
|
self.messageDecls = [ ]
|
||||||
self.transitionStmts = [ ]
|
self.transitionStmts = [ ]
|
||||||
|
self.startStates = [ ]
|
||||||
|
|
||||||
def addOuterNamespace(self, namespace):
|
def addOuterNamespace(self, namespace):
|
||||||
self.namespaces.insert(0, namespace)
|
self.namespaces.insert(0, namespace)
|
||||||
@ -315,17 +316,20 @@ class ANSWER:
|
|||||||
def direction(cls): return IN
|
def direction(cls): return IN
|
||||||
|
|
||||||
class State(Node):
|
class State(Node):
|
||||||
def __init__(self, loc, name):
|
def __init__(self, loc, name, start=False):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.start = start
|
||||||
def __eq__(self, o):
|
def __eq__(self, o):
|
||||||
return isinstance(o, State) and o.name == self.name
|
return (isinstance(o, State)
|
||||||
|
and o.name == self.name
|
||||||
|
and o.start == self.start)
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(repr(self))
|
return hash(repr(self))
|
||||||
def __ne__(self, o):
|
def __ne__(self, o):
|
||||||
return not (self == o)
|
return not (self == o)
|
||||||
def __repr__(self): return '<State %r>'% (self.name)
|
def __repr__(self): return '<State %r start=%s>'% (self.name, self.start)
|
||||||
def __str__(self): return '<State %s>'% (self.name)
|
def __str__(self): return '<State %s start=%s>'% (self.name, self.start)
|
||||||
|
|
||||||
class Param(Node):
|
class Param(Node):
|
||||||
def __init__(self, loc, typespec, name):
|
def __init__(self, loc, typespec, name):
|
||||||
|
@ -403,12 +403,13 @@ def p_TransitionStmtsNonEmpty(p):
|
|||||||
|
|
||||||
def p_TransitionStmt(p):
|
def p_TransitionStmt(p):
|
||||||
"""TransitionStmt : OptionalStart STATE State ':' Transitions"""
|
"""TransitionStmt : OptionalStart STATE State ':' Transitions"""
|
||||||
|
p[3].start = p[1]
|
||||||
p[0] = TransitionStmt(locFromTok(p, 2), p[3], p[5])
|
p[0] = TransitionStmt(locFromTok(p, 2), p[3], p[5])
|
||||||
|
|
||||||
def p_OptionalStart(p):
|
def p_OptionalStart(p):
|
||||||
"""OptionalStart : START
|
"""OptionalStart : START
|
||||||
| """
|
| """
|
||||||
pass
|
p[0] = (len(p) == 2) # True iff 'start' specified
|
||||||
|
|
||||||
def p_Transitions(p):
|
def p_Transitions(p):
|
||||||
"""Transitions : Transitions Transition
|
"""Transitions : Transitions Transition
|
||||||
|
@ -318,7 +318,7 @@ With this information, it finally type checks the AST.'''
|
|||||||
if not runpass(CheckTypes(self.errors)):
|
if not runpass(CheckTypes(self.errors)):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if (tu.protocol.startState is not None
|
if (len(tu.protocol.startStates)
|
||||||
and not runpass(CheckStateMachine(self.errors))):
|
and not runpass(CheckStateMachine(self.errors))):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -471,9 +471,11 @@ class GatherDecls(TcheckVisitor):
|
|||||||
|
|
||||||
p.states = { }
|
p.states = { }
|
||||||
if len(p.transitionStmts):
|
if len(p.transitionStmts):
|
||||||
p.startState = p.transitionStmts[0]
|
p.startStates = [ ts for ts in p.transitionStmts
|
||||||
else:
|
if ts.state.start ]
|
||||||
p.startState = None
|
if 0 == len(p.startStates):
|
||||||
|
p.startStates = [ p.transitionStmts[0] ]
|
||||||
|
|
||||||
# declare each state before decorating their mention
|
# declare each state before decorating their mention
|
||||||
for trans in p.transitionStmts:
|
for trans in p.transitionStmts:
|
||||||
p.states[trans.state] = trans
|
p.states[trans.state] = trans
|
||||||
@ -923,8 +925,9 @@ upon trigger |t|, or None if |t| is not a trigger in |S|.'''
|
|||||||
visited.add(ts.state)
|
visited.add(ts.state)
|
||||||
for outedge in ts.transitions:
|
for outedge in ts.transitions:
|
||||||
explore(p.states[outedge.toState])
|
explore(p.states[outedge.toState])
|
||||||
|
|
||||||
explore(p.startState)
|
for root in p.startStates:
|
||||||
|
explore(root)
|
||||||
for ts in p.transitionStmts:
|
for ts in p.transitionStmts:
|
||||||
if ts.state not in visited:
|
if ts.state not in visited:
|
||||||
self.error(ts.loc, "unreachable state `%s' in protocol `%s'",
|
self.error(ts.loc, "unreachable state `%s' in protocol `%s'",
|
||||||
|
Loading…
Reference in New Issue
Block a user