#include "WfAnalyzer.h"
namespace
{
namespace
{
namespace
{
using
namespace
collections
;
using
namespace
parsing
;
using
namespace
reflection
;
using
namespace
reflection
::
description
;
void
(
*
,
*
)
{
auto
=
<
>();
->
block
;
auto
=
L"<switch>"
+
(
->
++);
{
auto
=
->
->
.
()];
auto
=
<
>();
decl
.
=
varName
;
decl
(
result
.
.
());
decl
(
->
,
true
);
auto
=
<
>();
stat
decl
;
block
.
(
stat
);
}
<
>
;
auto
= &
rootIfStat
;
FOREACH(Ptr<WfSwitchCase>, switchCase, node->caseBranches)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
switchCase
);)
{
auto
=
<
>();
*
tailIfStat
ifStat
;
tailIfStat
= &
ifStat
;
{
auto
=
<
>();
refExpr
.
=
varName
;
auto
=
<
>();
inferExpr
(
switchCase
,
true
);
{
auto
=
->
switchCase
.
()];
inferExpr
(
result
.
.
());
}
auto
=
<
>();
compare
refExpr
;
compare
inferExpr
;
compare
=
::
;
ifStat
compare
;
}
ifStat
(
switchCase
,
true
);
}
if
(
->
)
{
*
tailIfStat
(
->
,
true
);
}
if
(
rootIfStat
)
{
block
.
(
rootIfStat
);
}
}
<
>
GenerateForEachStepStatement
(
*
)
{
auto
=
<
>();
refVar1
.
->
.
;
auto
=
<
>();
refVar2
.
->
.
;
auto
=
<
>();
one
.
=
L"1"
;
auto
=
<
>();
stepExpr
refVar2
;
stepExpr
one
;
stepExpr
=
->
==
::
?
::
:
::
;
auto
=
<
>();
assignExpr
refVar1
;
assignExpr
stepExpr
;
assignExpr
=
::
;
auto
=
<
>();
stat
assignExpr
;
return
stat
;
}
class
CopyForEachRangeBodyVisitor
:
public
CopyWithExpandVirtualVisitor
{
public
:
*
;
*
;
CopyForEachRangeBodyVisitor
(
*
,
*
)
:
CopyWithExpandVirtualVisitor
(
true
)
, manager(
)
, forEach(
)
{
}
void
(
*
)
{
auto
=
->
];
while
(
scope
)
{
if
(
scope
.
<
>())
{
break
;
}
else
if
(
scope
.
<
>())
{
if
(
scope
)
{
break
;
}
else
{
auto
=
<
>();
block
.
(
GenerateForEachStepStatement
(
));
block
.
(
<
>());
((
<
>)
block
,
->
);
block
;
return
;
}
}
scope
scope
;
}
copy_visitor
::
::
(
);
}
};
void
(
*
,
*
)
{
auto
=
<
>();
->
block
;
if
(
auto
=
->
.
<
>())
{
auto
=
L"<for-begin>"
+
->
.
;
auto
=
L"<for-end>"
+
->
.
;
{
auto
=
->
range
.
()];
auto
=
<
>();
decl
.
=
varBegin
;
decl
(
result
.
.
());
decl
(
range
,
true
);
if
(
range
==
::
)
{
auto
=
<
>();
one
.
=
L"1"
;
auto
=
<
>();
addExpr
decl
;
addExpr
one
;
addExpr
=
::
;
decl
addExpr
;
}
auto
=
<
>();
stat
decl
;
block
.
(
stat
);
}
{
auto
=
->
range
.
()];
auto
=
<
>();
decl
.
=
varEnd
;
decl
(
result
.
.
());
decl
(
range
,
true
);
if
(
range
==
::
)
{
auto
=
<
>();
one
.
=
L"1"
;
auto
=
<
>();
subExpr
decl
;
subExpr
one
;
subExpr
=
::
;
decl
subExpr
;
}
auto
=
<
>();
stat
decl
;
block
.
(
stat
);
}
{
auto
=
<
>();
refBegin
.
=
->
==
::
?
varBegin
:
varEnd
;
auto
=
<
>();
decl
.
->
.
;
decl
refBegin
;
auto
=
<
>();
stat
decl
;
block
.
(
stat
);
}
{
auto
=
<
>();
{
auto
=
<
>();
refVar
.
->
.
;
auto
=
<
>();
refBegin
.
=
->
==
::
?
varEnd
:
varBegin
;
auto
=
<
>();
compare
refVar
;
compare
refBegin
;
compare
=
->
==
::
?
::
:
::
;
whileStat
compare
;
}
{
auto
=
<
>();
whileStat
whileBlock
;
{
CopyForEachRangeBodyVisitor
(
,
);
->
(&
visitor
);
whileBlock
.
(
visitor
.
.
<
>());
}
whileBlock
.
(
GenerateForEachStepStatement
(
));
}
block
.
(
whileStat
);
}
}
else
{
auto
=
L"<for-enumerable>"
+
->
.
;
auto
=
L"<for-enumerator>"
+
->
.
;
{
auto
=
<
>();
decl
.
=
varEnum
;
if
(
->
==
::
)
{
auto
=
<
>();
inferExpr
(
->
,
true
);
inferExpr
(
<
<
>>::
().
());
decl
inferExpr
;
}
else
{
auto
=
<
>();
refMethod
GetExpressionFromTypeDescriptor
(
description
::
<
>());
refMethod
.
=
L"ReverseEnumerable"
;
auto
=
<
>();
refCall
refMethod
;
refCall
.
(
(
->
,
true
));
decl
refCall
;
}
auto
=
<
>();
stat
decl
;
block
.
(
stat
);
}
{
auto
=
<
>();
refEnum
.
=
varEnum
;
auto
=
<
>();
refMethod
refEnum
;
refMethod
.
=
L"CreateEnumerator"
;
auto
=
<
>();
callExpr
refMethod
;
auto
=
<
>();
decl
.
=
varIter
;
decl
callExpr
;
auto
=
<
>();
stat
decl
;
block
.
(
stat
);
}
{
auto
=
<
>();
{
auto
=
<
>();
refIter
.
=
varIter
;
auto
=
<
>();
refMethod
refIter
;
refMethod
.
=
L"Next"
;
auto
=
<
>();
callExpr
refMethod
;
whileStat
callExpr
;
}
{
auto
=
<
>();
whileStat
whileBlock
;
{
auto
=
<
>();
refIter
.
=
varIter
;
auto
=
<
>();
refMethod
refIter
;
refMethod
.
=
L"GetCurrent"
;
auto
=
<
>();
callExpr
refMethod
;
auto
=
<
>();
castExpr
callExpr
;
castExpr
=
::
;
{
auto
=
->
];
auto
=
parentScope
->
.
]
0
];
castExpr
(
symbol
.
());
}
auto
=
<
>();
decl
.
->
.
;
decl
castExpr
;
auto
=
<
>();
stat
decl
;
whileBlock
.
(
stat
);
}
whileBlock
.
(
(
->
,
true
));
}
block
.
(
whileStat
);
}
}
}
class
ExpandCoProviderStatementVisitor
:
public
CopyWithExpandVirtualVisitor
{
public
:
*
;
ExpandCoProviderStatementVisitor
(
*
)
:
CopyWithExpandVirtualVisitor
(
true
)
, manager(
)
{
}
void
(
*
)
override
{
auto
=
->
].
;
auto
=
<
>();
{
auto
=
<
>();
refImpl
.
=
L"<co-impl>"
;
auto
=
<
>();
funcExpr
GetExpressionFromTypeDescriptor
(
opInfo
->
());
funcExpr
.
opInfo
->
();
auto
=
<
>();
callExpr
funcExpr
;
callExpr
.
(
refImpl
);
if
(
->
)
{
auto
=
(
->
);
{
auto
=
->
].
();
auto
=
scope
->
();
if
(
auto
=
functionScope
->
.
<
>())
{
auto
=
(
scope
,
funcDecl
);
if
(
auto
=
returnType
()->
(
L"StoreResult"
,
true
))
{
=
group
->GetMethodCount();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
group
->GetMethod(
i
);
if
(
method
->IsStatic() &&
method
->GetParameterCount() ==
1
)
{
auto
=
GetExpressionFromTypeDescriptor
(
returnType
());
auto
=
<
>();
refStoreResult
refType
;
refStoreResult
.
=
L"StoreResult"
;
auto
=
<
>();
callExpr
refStoreResult
;
callExpr
.
(
returnValue
);
returnValue
callExpr
;
break
;
}
}
}
}
}
callExpr
.
(
returnValue
);
}
auto
=
<
>();
stat
callExpr
;
block
.
(
stat
);
}
block
.
(
<
>());
(
<
>(
block
),
->
);
block
;
}
void
(
*
)
override
{
auto
=
->
].
;
auto
=
<
>();
{
auto
=
<
>();
refImpl
.
=
L"<co-impl>"
;
auto
=
<
>();
funcExpr
GetExpressionFromTypeDescriptor
(
opInfo
->
());
funcExpr
.
opInfo
->
();
auto
=
<
>();
callExpr
funcExpr
;
callExpr
.
(
refImpl
);
FOREACH(Ptr<WfExpression>, argument, node->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
callExpr
.
(
(
argument
));
}
auto
=
<
>();
stat
callExpr
;
auto
=
<
>();
pauseBlock
.
(
stat
);
auto
=
<
>();
pauseStat
pauseBlock
;
block
.
(
pauseStat
);
}
{
<
>
;
if
(
->
.
==
L""
)
{
ifHasResultStat
<
>();
{
auto
=
<
>();
refCoResult
.
=
L"<co-result>"
;
auto
=
<
>();
testExpr
refCoResult
;
testExpr
=
::
;
ifHasResultStat
testExpr
;
}
}
auto
=
<
>();
{
auto
=
<
>();
refCoResult
.
=
L"<co-result>"
;
auto
=
<
>();
refFailure
refCoResult
;
refFailure
.
=
L"Failure"
;
auto
=
<
>();
testExpr
refFailure
;
testExpr
=
::
;
ifStat
testExpr
;
}
{
auto
=
<
>();
refCoResult
.
=
L"<co-result>"
;
auto
=
<
>();
refFailure
refCoResult
;
refFailure
.
=
L"Failure"
;
auto
=
<
WfRaiseExceptionStatement
>();
raiseStat
refFailure
;
auto
=
<
>();
ifBlock
.
(
raiseStat
);
ifStat
ifBlock
;
}
if
(
ifHasResultStat
)
{
auto
=
<
>();
ifHasResultStat
ifBlock
;
ifBlock
.
(
ifStat
);
block
.
(
ifHasResultStat
);
}
else
{
block
.
(
ifStat
);
}
}
if
(
->
.
!=
L""
)
{
auto
=
<
>();
refCoResult
.
=
L"<co-result>"
;
auto
=
<
>();
refResult
refCoResult
;
refResult
.
=
L"Result"
;
auto
=
->
].
;
auto
=
<
>();
refCastResult
GetExpressionFromTypeDescriptor
(
castResultInfo
->
());
refCastResult
.
=
L"CastResult"
;
auto
=
<
>();
callExpr
refCastResult
;
callExpr
.
(
refResult
);
auto
=
<
>();
varDecl
.
->
.
;
varDecl
callExpr
;
auto
=
<
>();
stat
varDecl
;
block
.
(
stat
);
}
(
<
>(
block
),
->
);
block
;
}
void
(
*
)
override
{
auto
=
<
>();
FOREACH(Ptr<WfStatement>, statement, node->statements)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
statement
);)
{
statement
SearchUntilNonVirtualStatement
(
statement
);
if
(
auto
=
statement
.
<
>())
{
coOperatorStat
(
this
);
(
block
,
.
<
>()
,
true
);
}
else
{
block
.
(
(
statement
));
}
}
(
<
>(
block
),
->
);
block
;
}
};
void
ExpandCoProviderStatement
(
*
,
*
)
{
auto
=
->
].
();
auto
=
scope
->
();
auto
=
functionScope
->
.
<
>();
auto
=
->
funcDecl
.
()];
auto
=
providerScope
[
L"$PROVIDER"
][
0
]->typeInfo;
auto
=
providerScope
[
L"$IMPL"
][
0
]->typeInfo;
auto
=
<
>();
{
coroutineExpr
.
=
L"<co-result>"
;
coroutineExpr
ExpandCoProviderStatementVisitor
(
).
(
->
);
}
->
.
(
coroutineExpr
,
::
(
providerType
));
auto
=
<
>();
{
auto
=
<
>();
creatorExpr
creatorDecl
;
creatorDecl
=
::
;
creatorDecl
(
<
<
>>::
().
());
{
auto
=
<
>();
creatorDecl
.
(
argument
);
argument
.
=
L"<co-impl>"
;
argument
=
(
implType
.Obj());
}
auto
=
<
>();
creatorDecl
block
;
auto
=
<
>();
returnStat
coroutineExpr
;
block
.
(
returnStat
);
}
auto
=
<
>();
{
auto
=
(
functionScope
,
funcDecl
);
auto
=
->
].
;
auto
=
<
>();
funcExpr
GetExpressionFromTypeDescriptor
(
creatorInfo
->
());
funcExpr
.
creatorInfo
->
();
auto
=
<
>();
callExpr
funcExpr
;
callExpr
.
(
creatorExpr
);
if
(
funcReturnType
() ==
description
::
<
void
>())
{
auto
=
<
>();
stat
callExpr
;
providerBlock
.
(
stat
);
}
else
{
if
(
(
funcReturnType
.
(),
creatorInfo
->
()))
{
auto
=
<
>();
stat
callExpr
;
providerBlock
.
(
stat
);
}
else
if
(
funcReturnType
() ==
creatorInfo
->
()->
())
{
auto
=
<
>();
castExpr
=
::
;
castExpr
(
funcReturnType
.
());
castExpr
callExpr
;
auto
=
<
>();
stat
castExpr
;
providerBlock
.
(
stat
);
}
else
{
{
auto
=
<
>();
varDecl
.
=
L"<co-mixin-source-variable>"
;
varDecl
callExpr
;
auto
=
<
>();
stat
varDecl
;
providerBlock
.
(
stat
);
}
{
auto
=
<
>();
refExpr
.
=
L"<co-mixin-source-variable>"
;
auto
=
<
>();
castExpr
(
funcReturnType
.
());
castExpr
refExpr
;
auto
=
<
>();
stat
castExpr
;
providerBlock
.
(
stat
);
}
}
}
}
->
providerBlock
;
}
}
}
}