#include "WfAnalyzer.h"
namespace
{
namespace
{
namespace
{
using
namespace
collections
;
using
namespace
reflection
;
using
namespace
reflection
::
description
;
<
>
GenerateStateMachineInvalidId
()
{
auto
=
<
>();
refOne
.
=
L"1"
;
auto
=
<
>();
refInvalid
=
::
;
refInvalid
refOne
;
return
refInvalid
;
}
class
ExpandStateMachineStatementVisitor
:
public
copy_visitor
::
,
public
copy_visitor
::
VirtualCseStatementVisitor
,
public
::
{
protected
:
*
;
*
;
public
:
ExpandStateMachineStatementVisitor
(
*
,
*
)
:manager(
)
, smInfo(
)
{
}
vl
::
<
>
(
vl
::
<
>
)
override
{
return
(
,
true
);
}
vl
::
<
>
(
vl
::
<
>
)
override
{
return
(
);
}
vl
::
<
>
(
vl
::
<
>
)
override
{
if
(!
)
return
nullptr
;
(
this
);
return
.
<
>();
}
vl
::
<
vl
::
parsing
::
>
(
*
)
override
{
->
((
::
*)
this
);
return
;
}
vl
::
<
vl
::
parsing
::
>
(
*
)
override
{
CHECK_FAIL(L"ExpandStateMachineStatementVisitor::Dispatch(WfCoroutineStatement*)#ValidateStatementStructure should check coroutine statement's location.");
do
{
throw
(
L"ExpandStateMachineStatementVisitor::Dispatch(WfCoroutineStatement*)#ValidateStatementStructure should check coroutine statement's location."
);}
while
(
0
);
}
vl
::
<
vl
::
parsing
::
>
(
*
)
override
{
->
((
::
*)
this
);
return
;
}
<
>
()
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refInput
refThis
;
refInput
.
=
L"stateMachineInput"
;
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refInput
;
assignExpr
GenerateStateMachineInvalidId
();
auto
=
<
>();
exprStat
assignExpr
;
return
exprStat
;
}
void
(
const
&
,
*
,
<
>
,
<
>&
,
<
>&
)
{
=
(
->
])
.
([=](
<
>
)
{
return
symbol
.
<
>();
})
.
([=](
<
>
)
{
return
decl
nullptr
;
})
.
();
auto
=
<
>();
.
(
switchCase
);
{
auto
=
<
>();
refInputId
.
(
->
]);
switchCase
refInputId
;
}
<
>();
switchCase
;
.
(
GenerateIngoreInputStatement
());
}
void
(
*
)
override
{
auto
=
->
]
()->
.
();
auto
=
<
>();
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refInput
refThis
;
refInput
.
=
L"stateMachineInput"
;
auto
=
<
>();
compareInput
=
::
;
compareInput
refInput
;
compareInput
GenerateStateMachineInvalidId
();
auto
=
<
>();
block
.
(
ifStat
);
ifStat
compareInput
;
auto
=
<
>();
ifStat
trueBlock
;
trueBlock
.
(
<
>());
}
auto
=
<
>();
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refInput
refThis
;
refInput
.
=
L"stateMachineInput"
;
switchStat
refInput
;
}
block
.
(
switchStat
);
FOREACH(Ptr<WfStateSwitchCase>, stateSwitchCase, node->caseBranches)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
stateSwitchCase
);)
{
<
>
;
<
>
;
(
stateSwitchCase
.
,
smcScope
,
switchStat
,
input
,
caseBlock
);
FOREACH_INDEXER(Ptr<WfStateSwitchArgument>, argument, index, stateSwitchCase->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
stateSwitchCase
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
if
(
bool
=
true
)
for
(
=
0
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);
index
++)
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refArgument
refThis
;
refArgument
.
->
input
index
].
()]
();
auto
=
<
>();
varDecl
.
argument
.
;
varDecl
refArgument
;
auto
=
<
>();
varStat
varDecl
;
caseBlock
.
(
varStat
);
}
caseBlock
.
(
(
stateSwitchCase
));
(
<
>(
caseBlock
),
stateSwitchCase
);
}
if
(
->
==
::
)
{
auto
=
(
->
.
())
.
(
(
->
)
.Select([](
<
>
) {
return
switchCase
.
; })
);
FOREACH(WString, inputName, invalidInputs)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
invalidInputs
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
inputName
);)
{
<
>
;
<
>
;
(
inputName
,
smcScope
,
switchStat
,
input
,
caseBlock
);
{
auto
=
<
>();
refException
.
=
L"Method \""
+
inputName
+
L"\" of class \""
+
->
input
.
()]
()->
() +
L"\" cannot be called at this moment."
;
auto
=
<
WfRaiseExceptionStatement
>();
raiseStat
refException
;
caseBlock
.
(
raiseStat
);
}
}
}
auto
=
<
>();
switch
(
->
)
{
case
::
:
case
::
:
break
;
case
::
:
{
auto
=
<
>();
gotoStat
.
=
L"<state-label>OUT_OF_STATE_MACHINE"
;
defaultBlock
.
(
gotoStat
);
}
break
;
case
::
:
{
defaultBlock
.
(
GenerateIngoreInputStatement
());
}
break
;
case
::
:
{
defaultBlock
.
(
GenerateIngoreInputStatement
());
auto
=
<
>();
gotoStat
.
=
L"<state-label>OUT_OF_STATE_MACHINE"
;
defaultBlock
.
(
gotoStat
);
}
break
;
}
if
(
defaultBlock
.
() >
0
)
{
switchStat
defaultBlock
;
}
(
<
>(
block
),
->
);
block
;
}
void
(
*
)
override
{
auto
=
->
]
()->
.
();
auto
=
(
smcScope
->
->
.
])
.
([=](
<
>
)
{
return
symbol
.
<
>();
})
.
([=](
<
>
)
{
return
decl
nullptr
;
})
.
();
auto
=
<
>();
FOREACH_INDEXER(Ptr<WfFunctionArgument>, argument, index, stateDecl->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
stateDecl
->arguments);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
if
(
bool
=
true
)
for
(
=
0
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);
index
++)
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refArgument
refThis
;
refArgument
.
->
argument
.
()]
();
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refArgument
;
assignExpr
(
->
index
]);
auto
=
<
>();
exprStat
assignExpr
;
block
.
(
exprStat
);
}
switch
(
->
)
{
case
::
:
{
{
auto
=
<
>();
refState
.
=
L"<state>state"
;
auto
=
<
>();
refStateId
.
(
->
->
.
]);
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refState
;
assignExpr
refStateId
;
auto
=
<
>();
exprStat
assignExpr
;
block
.
(
exprStat
);
}
{
auto
=
<
>();
gotoStat
.
=
L"<state-label>OUT_OF_CURRENT_STATE"
;
block
.
(
gotoStat
);
}
}
break
;
case
::
:
{
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refCoroutine
refThis
;
refCoroutine
.
=
L"<state>CreateCoroutine"
;
auto
=
<
>();
refStateId
.
(
->
->
.
]);
auto
=
<
>();
callExpr
refCoroutine
;
callExpr
.
(
refStateId
);
auto
=
<
>();
exprStat
callExpr
;
block
.
(
exprStat
);
}
{
block
.
(
<
>());
}
}
break
;
}
(
<
>(
block
),
->
);
block
;
}
};
void
(
*
,
WfStateMachineDeclaration
*
)
{
auto
&
=
->
];
FOREACH(Ptr<WfStateInput>, input, node->inputs)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
input
);)
{
smInfo
.
(
input
.
,
smInfo
.
());
FOREACH(Ptr<WfFunctionArgument>, argument, input->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
input
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
auto
=
->
argument
.
()];
auto
=
<
>();
varDecl
.
fieldInfo
();
varDecl
(
fieldInfo
());
varDecl
(
fieldInfo
());
auto
=
<
>();
classMember
=
::
;
varDecl
classMember
;
auto
=
<
>();
att
.
=
L"cpp"
;
att
.
=
L"Private"
;
varDecl
.
(
att
);
->
.
(
varDecl
);
->
.
(
varDecl
,
fieldInfo
);
}
}
smInfo
.
(
L""
,
0
);
FOREACH(Ptr<WfStateDeclaration>, state, node->states)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
state
);)
{
if
(
state
.
!=
L""
)
{
smInfo
.
(
state
.
,
smInfo
.
());
}
FOREACH(Ptr<WfFunctionArgument>, argument, state->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
state
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
auto
=
->
argument
.
()];
auto
=
<
>();
varDecl
.
fieldInfo
();
varDecl
(
fieldInfo
());
varDecl
(
fieldInfo
());
auto
=
<
>();
classMember
=
::
;
varDecl
classMember
;
auto
=
<
>();
att
.
=
L"cpp"
;
att
.
=
L"Private"
;
varDecl
.
(
att
);
->
.
(
varDecl
);
->
.
(
varDecl
,
fieldInfo
);
}
}
FOREACH(Ptr<WfStateInput>, input, node->inputs)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
input
);)
{
auto
=
->
input
.
()];
auto
=
<
>();
funcDecl
=
::
;
funcDecl
.
methodInfo
();
funcDecl
(
methodInfo
());
FOREACH_INDEXER(Ptr<WfFunctionArgument>, argument, index, input->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
input
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
if
(
bool
=
true
)
for
(
=
0
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);
index
++)
{
auto
=
<
>();
funcArgument
.
argument
.
;
funcArgument
(
methodInfo
(
index
)->
());
funcDecl
.
(
funcArgument
);
}
auto
=
<
>();
classMember
=
::
;
funcDecl
classMember
;
->
.
(
funcDecl
);
->
.
(
funcDecl
,
methodInfo
);
auto
=
<
>();
funcDecl
block
;
{
auto
=
<
>();
{
auto
=
<
>();
refInit
<
>();
refInit
.
=
L"stateMachineInitialized"
;
auto
=
<
>();
notExpr
=
::
;
notExpr
refInit
;
auto
=
<
>();
ifStat
notExpr
;
ifStat
trueBlock
;
block
.
(
ifStat
);
}
{
auto
=
<
>();
refInit
<
>();
refInit
.
=
L"stateMachineInitialized"
;
auto
=
<
>();
refTrue
=
::
;
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refInit
;
assignExpr
refTrue
;
auto
=
<
>();
exprStat
assignExpr
;
trueBlock
.
(
exprStat
);
}
{
auto
=
<
>();
refCC
<
>();
refCC
.
smInfo
();
auto
=
<
>();
refZero
.
=
L"0"
;
auto
=
<
>();
callExpr
refCC
;
callExpr
.
(
refZero
);
auto
=
<
>();
exprStat
callExpr
;
trueBlock
.
(
exprStat
);
}
{
auto
=
<
>();
refResume
<
>();
refResume
.
=
L"ResumeStateMachine"
;
auto
=
<
>();
callExpr
refResume
;
auto
=
<
>();
exprStat
callExpr
;
trueBlock
.
(
exprStat
);
}
}
{
auto
=
<
>();
refInput
<
>();
refInput
.
=
L"stateMachineInput"
;
auto
=
<
>();
refInputId
.
(
smInfo
input
.
]);
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refInput
;
assignExpr
refInputId
;
auto
=
<
>();
exprStat
assignExpr
;
block
.
(
exprStat
);
}
FOREACH_INDEXER(Ptr<WfFunctionArgument>, argument, index, input->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
input
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
if
(
bool
=
true
)
for
(
=
0
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);
index
++)
{
auto
=
<
>();
refField
<
>();
refField
.
->
argument
.
()]
();
auto
=
<
>();
refArgument
.
methodInfo
(
index
)->
();
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refField
;
assignExpr
refArgument
;
auto
=
<
>();
exprStat
assignExpr
;
block
.
(
exprStat
);
}
{
auto
=
<
>();
refResume
<
>();
refResume
.
=
L"ResumeStateMachine"
;
auto
=
<
>();
callExpr
refResume
;
auto
=
<
>();
exprStat
callExpr
;
block
.
(
exprStat
);
}
}
{
auto
=
<
>();
funcDecl
=
::
;
funcDecl
.
smInfo
();
funcDecl
(
<
void
>::
().
());
{
auto
=
smInfo
(
0
);
auto
=
<
>();
funcArgument
.
parameterInfo
->
();
funcArgument
(
parameterInfo
->
());
funcDecl
.
(
funcArgument
);
}
auto
=
<
>();
classMember
=
::
;
funcDecl
classMember
;
auto
=
<
>();
att
.
=
L"cpp"
;
att
.
=
L"Private"
;
funcDecl
.
(
att
);
->
.
(
funcDecl
);
->
.
(
funcDecl
,
smInfo
);
auto
=
<
>();
funcDecl
block
;
{
auto
=
<
>();
varDecl
.
=
L"<state>stateMachineObject"
;
varDecl
<
>();
auto
=
<
>();
stat
varDecl
;
block
.
(
stat
);
}
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refCoroutine
refThis
;
refCoroutine
.
=
L"stateMachineCoroutine"
;
auto
=
<
>();
varDecl
.
=
L"<state>previousCoroutine"
;
varDecl
refCoroutine
;
auto
=
<
>();
stat
varDecl
;
block
.
(
stat
);
}
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refCoroutine
refThis
;
refCoroutine
.
=
L"stateMachineCoroutine"
;
auto
=
<
>();
auto
=
<
>();
coroutine
coroutineBlock
;
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refCoroutine
;
assignExpr
coroutine
;
auto
=
<
>();
exprStat
assignExpr
;
block
.
(
exprStat
);
{
auto
=
<
>();
coroutineBlock
.
(
tryStat
);
auto
=
<
>();
tryBlock
.
=
L"<state-label>OUT_OF_STATE_MACHINE"
;
tryStat
tryBlock
;
auto
=
<
>();
tryStat
finallyBlock
;
{
auto
=
<
>();
refStartState
.
=
L"<state>startState"
;
auto
=
<
>();
varDecl
.
=
L"<state>state"
;
varDecl
refStartState
;
auto
=
<
>();
stat
varDecl
;
tryBlock
.
(
stat
);
}
{
auto
=
<
>();
whileBlock
.
=
L"<state-label>OUT_OF_CURRENT_STATE"
;
{
auto
=
<
>();
refTrue
=
::
;
auto
=
<
>();
whileStat
refTrue
;
whileStat
whileBlock
;
tryBlock
.
(
whileStat
);
}
{
auto
=
<
>();
refStartState
.
=
L"<state>state"
;
auto
=
<
>();
varDecl
.
=
L"<state>currentState"
;
varDecl
refStartState
;
auto
=
<
>();
stat
varDecl
;
whileBlock
.
(
stat
);
}
{
auto
=
<
>();
refState
.
=
L"<state>state"
;
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refState
;
assignExpr
GenerateStateMachineInvalidId
();
auto
=
<
>();
exprStat
assignExpr
;
whileBlock
.
(
exprStat
);
}
{
auto
=
<
>();
refCurrentState
.
=
L"<state>currentState"
;
auto
=
<
>();
switchStat
refCurrentState
;
whileBlock
.
(
switchStat
);
FOREACH(Ptr<WfStateDeclaration>, state, node->states)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
state
);)
{
auto
=
<
>();
switchStat
.
(
switchCase
);
auto
=
<
>();
refStateId
.
(
smInfo
state
.
]);
switchCase
refStateId
;
auto
=
<
>();
switchCase
caseBlock
;
FOREACH(Ptr<WfFunctionArgument>, argument, state->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
state
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refArgument
refThis
;
refArgument
.
->
argument
.
()]
();
auto
=
<
>();
varDecl
.
argument
.
;
varDecl
refArgument
;
auto
=
<
>();
varStat
varDecl
;
caseBlock
.
(
varStat
);
}
caseBlock
.
(
ExpandStateMachineStatementVisitor
(
,
smInfo
.
()).
(
state
));
{
auto
=
<
>();
gotoStat
.
=
L"<state-label>OUT_OF_STATE_MACHINE"
;
caseBlock
.
(
gotoStat
);
}
(
<
>(
caseBlock
),
state
);
}
}
}
{
auto
=
<
>();
refThis
.
=
L"<state>stateMachineObject"
;
auto
=
<
>();
refCoroutine
refThis
;
refCoroutine
.
=
L"stateMachineCoroutine"
;
auto
=
<
>();
refPrevious
.
=
L"<state>previousCoroutine"
;
auto
=
<
>();
assignExpr
=
::
;
assignExpr
refCoroutine
;
assignExpr
refPrevious
;
auto
=
<
>();
exprStat
assignExpr
;
finallyBlock
.
(
exprStat
);
}
}
}
}
}
}
}
}