#include "WfAnalyzer.h"
namespace
{
namespace
{
namespace
{
using
namespace
collections
;
using
namespace
reflection
;
using
namespace
reflection
::
description
;
using
namespace
typeimpl
;
class
ExpandVirtualStatementVisitor
:
public
,
public
::
{
public
:
*
;
ExpandVirtualStatementVisitor
(
*
)
:manager(
)
{
}
void
(
*
)
override
{
(
,
);
}
void
(
*
)
override
{
(
,
);
}
void
(
*
)
override
{
ExpandCoProviderStatement
(
,
);
}
};
class
ValidateSemanticStatementVisitor
:
public
,
public
::
,
public
::
,
public
::
,
public
::
{
public
:
*
;
ValidateSemanticStatementVisitor
(
*
)
:manager(
)
{
}
void
(
*
)
override
{
}
void
(
*
)
override
{
}
void
(
*
)
override
{
auto
=
->
].
();
auto
=
scope
->
();
if
(
auto
=
functionScope
->
.
<
>())
{
auto
=
funcDecl
.
<
>();
if
(
providerStat
&& !
providerStat
)
{
auto
=
->
funcDecl
.
()];
auto
=
providerScope
[
L"$PROVIDER"
][
0
];
auto
=
providerScope
[
L"$IMPL"
][
0
];
if
(
providerSymbol
->typeInfo &&
implSymbol
->typeInfo)
{
if
(
auto
=
providerSymbol
->typeInfo->GetTypeDescriptor()->GetMethodGroupByName(
L"ReturnAndExit"
,
true
))
{
<
>
;
=
group
->GetMethodCount();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
group
->GetMethod(
i
);
if
(
method
->IsStatic())
{
if
(
method
->GetParameterCount() >
0
&&
(
implSymbol
->typeInfo.Obj(),
method
->GetParameter(
0
)->GetType()))
{
functions
.
(
::
(
method
));
}
}
}
if
(
functions
.
() !=
0
)
{
= -
1
;
<
<
>>
;
arguments
.
(
nullptr
);
if
(
->
)
{
arguments
.
(
->
);
}
(
,
,
nullptr
,
functions
,
arguments
,
selectedFunctionIndex
);
if
(
selectedFunctionIndex
!= -
1
)
{
->
.
(
,
functions
selectedFunctionIndex
]);
}
}
else
{
->
.
(
::
(
,
providerSymbol
->typeInfo.Obj()));
}
}
else
{
->
.
(
::
(
,
providerSymbol
->typeInfo.Obj()));
}
}
}
else
{
auto
=
(
scope
,
funcDecl
);
if
(
->
)
{
if
(
returnType
() ==
description
::
<
void
>())
{
->
.
(
::
(
));
}
else
{
(
,
->
,
returnType
);
}
}
else
if
(
returnType
() !=
::
||
returnType
() !=
description
::
<
void
>())
{
->
.
(
::
(
,
returnType
.
()));
}
}
}
else
{
if
(
->
)
{
->
.
(
::
(
));
}
}
}
void
(
*
)
override
{
<
>
=
(
,
->
,
0
);
if
(
type
)
{
if
(
type
() !=
::
)
{
->
.
(
::
(
,
type
.
()));
}
}
}
void
(
WfRaiseExceptionStatement
*
)
override
{
if
(
->
)
{
if
(
auto
=
(
,
->
,
nullptr
))
{
auto
=
<
>::
();
auto
=
<
<
>>::
();
if
(!
(
type
.
(),
stringType
.
(),
false
) && !
(
type
.
(),
exceptionType
.
(),
false
))
{
->
.
(
::
ExpressionCannotImplicitlyConvertToType
(
->
.
(),
type
.
(),
stringType
.
()));
}
}
}
}
void
(
*
)
override
{
if
(
->
)
{
auto
=
->
].
();
auto
=
scope
->
->
.
]
0
];
if
(!
(
symbol
.
()))
{
->
.
(
::
NullCannotImplicitlyConvertToType
(
->
.
(),
symbol
.
()));
}
(
,
->
,
nullptr
);
}
else
{
<
>
=
<
bool
>::
();
(
,
->
,
boolType
);
}
ValidateStatementSemantic
(
,
->
);
if
(
->
)
{
ValidateStatementSemantic
(
,
->
);
}
}
void
(
*
)
override
{
<
>
=
<
bool
>::
();
(
,
->
,
boolType
);
ValidateStatementSemantic
(
,
->
);
}
void
(
*
)
override
{
ValidateStatementSemantic
(
,
->
);
if
(
->
)
{
ValidateStatementSemantic
(
,
->
);
}
if
(
->
)
{
ValidateStatementSemantic
(
,
->
);
}
}
void
(
*
)
override
{
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
);)
{
ValidateStatementSemantic
(
,
statement
);
}
}
void
(
*
)
override
{
auto
=
->
].
();
=
0
;
while
(
scope
&& !
scope
->
)
{
if
(
auto
=
scope
->
.
<
>())
{
if
(
block
.
==
->
.
)
{
counter
++;
}
}
scope
=
scope
->
.
();
}
if
(
counter
==
0
)
{
->
.
(
::
(
));
}
else
if
(
counter
>
1
)
{
->
.
(
::
(
));
}
}
void
(
*
)
override
{
(
,
->
,
0
);
}
void
(
*
)
override
{
ValidateDeclarationSemantic
(
,
->
);
}
void
(
*
)
override
{
bool
=
->
;
=
->
.
();
->
((
::
*)
this
);
if
(!
expanded
&&
->
.
() ==
errorCount
)
{
ExpandVirtualStatementVisitor
(
);
->
(&
visitor
);
(
->
,
->
);
auto
=
->
];
if
(
parentScope
)
{
parentScope
parentScope
;
}
ContextFreeStatementDesugar
(
,
->
);
(
,
parentScope
,
->
);
->
checkedScopes_DuplicatedSymbol
.
(
parentScope
.
());
->
.
(
parentScope
.
());
if
(!
CheckScopes_DuplicatedSymbol
(
) || !
(
))
{
return
;
}
}
if
(
->
)
{
ValidateStatementSemantic
(
,
->
);
}
}
void
(
*
)
override
{
<
>
=
(
,
->
,
0
);
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
);)
{
<
>
;
if
(
IsExpressionDependOnExpectedType
(
,
switchCase
))
{
caseType
(
,
switchCase
,
type
);
}
else
{
caseType
(
,
switchCase
,
0
);
}
if
(
type
&&
caseType
)
{
if
(!
(
type
,
caseType
))
{
->
.
(
::
(
switchCase
.
(),
type
.
(),
caseType
.
()));
}
}
ValidateStatementSemantic
(
,
switchCase
);
}
if
(
->
)
{
ValidateStatementSemantic
(
,
->
);
}
}
void
(
*
)
override
{
<
>
=
GetEnumerableExpressionItemType
(
,
->
,
0
);
if
(
elementType
)
{
auto
=
->
].
();
auto
=
scope
->
->
.
]
0
];
symbol
elementType
;
symbol
(
elementType
.
());
}
ValidateStatementSemantic
(
,
->
);
}
void
(
*
)
override
{
auto
=
->
].
();
auto
=
scope
->
[
L"$PROVIDER"
][
0
];
auto
=
scope
->
[
L"$IMPL"
][
0
];
<
>
;
{
auto
=
scope
->
.
<
>();
funcReturnType
(
scope
->
.
(),
decl
);
}
*
=
nullptr
;
<
>
;
if
(
->
.
==
L""
)
{
if
(
funcReturnType
)
{
<
*>
;
unprocessed
.
(
funcReturnType
());
for
(
=
0
;
i
<
unprocessed
.
();
i
++)
{
auto
=
unprocessed
i
];
auto
=
td
->
() +
L"Coroutine"
;
if
((
selectedProviderTd
=
description
::
(
candidate
)))
{
break
;
}
else
{
candidates
.
(
candidate
);
}
=
td
->
GetBaseTypeDescriptorCount
();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
td
->
(
i
);
if
(!
unprocessed
.
(
baseTd
))
{
unprocessed
.
(
baseTd
);
}
}
}
}
}
else
{
<
>
,
;
auto
=
->
.
.
(
->
.
.
() -
1
);
if
(
->
(
scope
,
providerName
,
resolveResults
))
{
(
results
,
resolveResults
);
for
(
=
results
.
() -
1
;
i
>=
0
;
i
--)
{
auto
&
=
results
i
];
*
=
nullptr
;
if
(
result
.
&&
result
.
)
{
auto
=
result
.
->
() +
L"Coroutine"
;
providerTd
=
description
::
(
candidate
);
if
(
providerTd
)
{
selectedProviderTd
=
providerTd
;
}
else
{
candidates
.
(
candidate
);
}
}
if
(!
providerTd
)
{
results
.
(
i
);
}
}
if
(
results
.
() ==
1
)
{
goto
FINISH_SEARCHING;
}
else
if
(
results
.
() >
1
)
{
->
.
(
::
(
,
resolveResults
,
providerName
));
goto
SKIP_SEARCHING;
}
}
resolveResults
.
();
if
(
->
(
scope
,
providerName
+
L"Coroutine"
,
resolveResults
))
{
(
results
,
resolveResults
);
for
(
=
results
.
() -
1
;
i
>=
0
;
i
--)
{
auto
&
=
results
i
];
if
(
result
.
&&
result
.
)
{
selectedProviderTd
=
result
.
;
}
else
{
results
.
(
i
);
}
}
if
(
results
.
() ==
1
)
{
goto
FINISH_SEARCHING;
}
else
if
(
results
.
() >
1
)
{
->
.
(
::
(
,
resolveResults
,
providerName
));
goto
SKIP_SEARCHING;
}
}
candidates
.
(
providerName
);
candidates
.
(
providerName
+
L"Coroutine"
);
}
FINISH_SEARCHING:
if
(
selectedProviderTd
)
{
providerSymbol
->typeInfo =
<
>(
selectedProviderTd
,
::
);
if
(
funcReturnType
)
{
;
if
(
funcReturnType
() ==
description
::
<
void
>())
{
creatorName
=
L"CreateAndRun"
;
}
else
{
creatorName
=
L"Create"
;
}
if
(
auto
=
selectedProviderTd
->
(
creatorName
,
true
))
{
<
>
;
*
=
nullptr
;
*
=
nullptr
;
=
group
->
();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
group
->
(
i
);
if
(
method
->
())
{
if
(
method
->
() ==
1
)
{
auto
=
method
->
(
0
)->
();
if
(
creatorType
->
() ==
::
)
{
auto
=
creatorType
->
();
if
(
functionType
->
() ==
::
&&
functionType
->
() ==
2
&&
functionType
->
() ==
description
::
<
>()
)
{
auto
=
functionType
->
(
0
);
if
(
returnType
->
() ==
::
&&
returnType
->
() ==
description
::
<
>())
{
selectedImplType
=
functionType
->
(
1
);
selectedCreator
=
method
;
results
.
(
::
(
method
));
}
}
}
}
}
}
if
(
results
.
() ==
1
)
{
implSymbol
->typeInfo =
(
selectedImplType
);
->
.
(
,
::
(
selectedCreator
));
}
else
if
(
results
.
() >
1
)
{
->
.
(
::
(
,
results
,
creatorName
));
}
}
if
(!
implSymbol
->typeInfo)
{
if
(
funcReturnType
() ==
description
::
<
void
>())
{
->
.
(
::
CoProviderCreateAndRunNotExists
(
,
providerSymbol
->typeInfo.Obj()));
}
else
{
->
.
(
::
CoProviderCreateNotExists
(
,
providerSymbol
->typeInfo.Obj()));
}
}
}
}
else
{
->
.
(
::
(
,
candidates
));
}
SKIP_SEARCHING:
ValidateStatementSemantic
(
,
->
);
}
void
(
*
)
override
{
->
((
::
*)
this
);
}
void
(
*
)
override
{
if
(
->
)
{
ValidateStatementSemantic
(
,
->
);
}
}
void
(
*
)
override
{
auto
=
->
].
();
auto
=
scope
->
();
if
(
auto
=
functionScope
->
.
<
>())
{
if
(
funcDecl
.
<
>())
{
auto
=
->
funcDecl
.
()];
auto
=
providerScope
[
L"$PROVIDER"
][
0
];
auto
=
providerScope
[
L"$IMPL"
][
0
];
if
(
providerSymbol
->typeInfo &&
implSymbol
->typeInfo)
{
<
*>
;
auto
=
->
.
.
(
->
.
.
() -
1
);
if
(
auto
=
providerSymbol
->typeInfo->GetTypeDescriptor()->GetMethodGroupByName(
operatorName
+
L"AndRead"
,
true
))
{
groups
.
(
group
);
}
if
(
->
.
==
L""
)
{
if
(
auto
=
providerSymbol
->typeInfo->GetTypeDescriptor()->GetMethodGroupByName(
operatorName
+
L"AndPause"
,
true
))
{
groups
.
(
group
);
}
}
<
>
;
FOREACH(IMethodGroupInfo*, group, groups)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
groups
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
group
);)
{
=
group
->
();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
group
->
(
i
);
if
(
method
->
())
{
if
(
method
->
() >
0
&&
(
implSymbol
->typeInfo.Obj(),
method
->
(
0
)->
()))
{
functions
.
(
::
(
method
));
}
}
}
}
if
(
functions
.
() ==
0
)
{
->
.
(
::
(
,
providerSymbol
->typeInfo.Obj()));
}
else
{
= -
1
;
=
->
.
();
<
<
>>
;
arguments
.
(
nullptr
);
(
arguments
,
->
,
true
);
(
,
,
nullptr
,
functions
,
arguments
,
selectedFunctionIndex
);
if
(
selectedFunctionIndex
!= -
1
)
{
->
.
(
,
functions
selectedFunctionIndex
]);
if
(
->
.
!=
L""
&&
->
.
() ==
oldErrorCount
)
{
auto
=
scope
->
->
.
]
0
];
<
*>
;
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
);)
{
=
->
.
().
(
argument
.
());
if
(
index
!= -
1
)
{
auto
=
->
.
()
index
].
;
if
(!
types
.
(
type
.
()))
{
types
.
(
type
.
());
if
(
auto
=
type
()->
(
L"CastResult"
,
true
))
{
=
group
->GetMethodCount();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
group
->GetMethod(
i
);
if
(
method
->IsStatic())
{
if
(
method
->GetParameterCount() ==
1
&&
method
->GetParameter(
0
)->GetType()->GetTypeDescriptor() ==
description
::
<
>() &&
method
->GetReturn()->GetTypeDescriptor() !=
description
::
<
void
>()
)
{
->
.
(
,
::
(
method
));
symbol
=
(
method
->GetReturn());
break
;
}
}
}
}
}
}
}
if
(!
symbol
)
{
->
.
(
::
CoOperatorCannotResolveResultType
(
,
types
));
}
}
}
}
}
}
}
}
void
(
*
)
override
{
->
((
::
*)
this
);
}
void
(
*
)
override
{
auto
=
->
]
()->
.
();
CHECK_ERROR(smcScope->ownerNode.Cast<WfClassDeclaration>(), L"ValidateSemanticStatementVisitor::Visit(WfStateSwitchStatement*)#ValidateStatementStructure should check state machine statements' location.");
do
{
if
(!(
smcScope
->
.
<
>()))
throw
(
L"ValidateSemanticStatementVisitor::Visit(WfStateSwitchStatement*)#ValidateStatementStructure should check state machine statements' location."
);}
while
(
0
);
FOREACH(Ptr<WfStateSwitchCase>, switchCase, node->caseBranches)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
switchCase
);)
{
auto
=
->
switchCase
.
()].
();
<
>
;
{
=
smcScope
->
.
().
(
switchCase
.
);
if
(
index
!= -
1
)
{
inputSymbol
smcScope
->
.
(
index
)
0
];
}
}
if
(!
inputSymbol
|| !
inputSymbol
.
<
>())
{
->
.
(
::
(
switchCase
.
()));
}
else
{
auto
=
->
smcScope
->
.
<
>().
()].
();
auto
=
td
->
(
switchCase
.
,
false
)->
(
0
);
if
(
switchCase
.
() !=
inputMethod
->
())
{
->
.
(
::
StateSwitchArgumentCountNotMatch
(
switchCase
.
()));
}
else
{
FOREACH_INDEXER(Ptr<WfStateSwitchArgument>, argument, index, switchCase->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
switchCase
);
__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
=
caseScope
->
argument
.
]
0
];
argumentSymbol
(
inputMethod
->
(
index
)->
());
argumentSymbol
(
argumentSymbol
.
());
}
}
}
ValidateStatementSemantic
(
,
switchCase
);
}
}
void
(
*
)
override
{
auto
=
->
]
()->
.
();
CHECK_ERROR(smcScope->ownerNode.Cast<WfClassDeclaration>(), L"ValidateSemanticStatementVisitor::Visit(WfStateSwitchStatement*)#ValidateStatementStructure should check state machine statements' location.");
do
{
if
(!(
smcScope
->
.
<
>()))
throw
(
L"ValidateSemanticStatementVisitor::Visit(WfStateSwitchStatement*)#ValidateStatementStructure should check state machine statements' location."
);}
while
(
0
);
<
>
;
{
=
smcScope
->
.
().
(
->
.
);
if
(
index
!= -
1
)
{
stateSymbol
smcScope
->
.
(
index
)
0
];
}
}
if
(!
stateSymbol
|| !
stateSymbol
.
<
>())
{
->
.
(
::
(
));
}
else
{
auto
=
stateSymbol
.
<
>();
if
(
stateDecl
.
() !=
->
.
())
{
->
.
(
::
StateArgumentCountNotMatch
(
));
}
else
{
auto
=
->
stateDecl
.
()];
FOREACH_INDEXER(Ptr<WfExpression>, argument, index, node->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__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
=
stateScope
stateDecl
index
]
.
]
0
]
;
(
,
argument
,
typeInfo
);
}
}
}
}
static
void
(
<
>
,
*
)
{
ValidateSemanticStatementVisitor
(
);
(&
visitor
);
}
};
void
ValidateStatementSemantic
(
*
,
<
>
)
{
return
ValidateSemanticStatementVisitor
::
(
,
);
}
}
}
}