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.messageDecls = [ ]
|
||||
self.transitionStmts = [ ]
|
||||
self.startStates = [ ]
|
||||
|
||||
def addOuterNamespace(self, namespace):
|
||||
self.namespaces.insert(0, namespace)
|
||||
@ -315,17 +316,20 @@ class ANSWER:
|
||||
def direction(cls): return IN
|
||||
|
||||
class State(Node):
|
||||
def __init__(self, loc, name):
|
||||
def __init__(self, loc, name, start=False):
|
||||
Node.__init__(self, loc)
|
||||
self.name = name
|
||||
self.start = start
|
||||
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):
|
||||
return hash(repr(self))
|
||||
def __ne__(self, o):
|
||||
return not (self == o)
|
||||
def __repr__(self): return '<State %r>'% (self.name)
|
||||
def __str__(self): return '<State %s>'% (self.name)
|
||||
def __repr__(self): return '<State %r start=%s>'% (self.name, self.start)
|
||||
def __str__(self): return '<State %s start=%s>'% (self.name, self.start)
|
||||
|
||||
class Param(Node):
|
||||
def __init__(self, loc, typespec, name):
|
||||
|
@ -403,12 +403,13 @@ def p_TransitionStmtsNonEmpty(p):
|
||||
|
||||
def p_TransitionStmt(p):
|
||||
"""TransitionStmt : OptionalStart STATE State ':' Transitions"""
|
||||
p[3].start = p[1]
|
||||
p[0] = TransitionStmt(locFromTok(p, 2), p[3], p[5])
|
||||
|
||||
def p_OptionalStart(p):
|
||||
"""OptionalStart : START
|
||||
| """
|
||||
pass
|
||||
p[0] = (len(p) == 2) # True iff 'start' specified
|
||||
|
||||
def p_Transitions(p):
|
||||
"""Transitions : Transitions Transition
|
||||
|
@ -318,7 +318,7 @@ With this information, it finally type checks the AST.'''
|
||||
if not runpass(CheckTypes(self.errors)):
|
||||
return False
|
||||
|
||||
if (tu.protocol.startState is not None
|
||||
if (len(tu.protocol.startStates)
|
||||
and not runpass(CheckStateMachine(self.errors))):
|
||||
return False
|
||||
|
||||
@ -471,9 +471,11 @@ class GatherDecls(TcheckVisitor):
|
||||
|
||||
p.states = { }
|
||||
if len(p.transitionStmts):
|
||||
p.startState = p.transitionStmts[0]
|
||||
else:
|
||||
p.startState = None
|
||||
p.startStates = [ ts for ts in p.transitionStmts
|
||||
if ts.state.start ]
|
||||
if 0 == len(p.startStates):
|
||||
p.startStates = [ p.transitionStmts[0] ]
|
||||
|
||||
# declare each state before decorating their mention
|
||||
for trans in p.transitionStmts:
|
||||
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)
|
||||
for outedge in ts.transitions:
|
||||
explore(p.states[outedge.toState])
|
||||
|
||||
explore(p.startState)
|
||||
|
||||
for root in p.startStates:
|
||||
explore(root)
|
||||
for ts in p.transitionStmts:
|
||||
if ts.state not in visited:
|
||||
self.error(ts.loc, "unreachable state `%s' in protocol `%s'",
|
||||
|
Loading…
Reference in New Issue
Block a user