#include "WfAnalyzer.h"
namespace
{
namespace
{
namespace
{
using
namespace
collections
;
using
namespace
reflection
;
using
namespace
reflection
::
description
;
(
reflection
::
description
::
*
)
{
if
(
==
<
bool
>())
return
::
;
if
(
==
<
>())
return
::
;
if
(
==
<
>())
return
::
;
if
(
==
<
>())
return
::
;
if
(
==
<
>())
return
::
;
if
(
==
<
>())
return
::
;
if
(
==
<
>())
return
::
;
if
(
==
<
>())
return
::
;
if
(
==
<
>())
return
::
;
if
(
==
<
float
>())
return
::
;
if
(
==
<
double
>())
return
::
;
if
(
==
<
>())
return
::
;
switch
(
->
())
{
case
::
:
case
::
:
return
::
;
case
::
:
return
::
;
default
:
return
::
;
}
}
(
reflection
::
description
::
*
)
{
*
=
->
();
return
(
td
);
}
<
reflection
::
description
::
>
CreateTypeInfoFromTypeFlag
(
)
{
switch
(
)
{
case
::
:
return
<
bool
>::
();
case
::
:
return
<
>::
();
case
::
:
return
<
>::
();
case
::
:
return
<
>::
();
case
::
:
return
<
>::
();
case
::
:
return
<
>::
();
case
::
:
return
<
>::
();
case
::
:
return
<
>::
();
case
::
:
return
<
>::
();
case
::
:
return
<
float
>::
();
case
::
:
return
<
double
>::
();
case
::
:
return
<
>::
();
default
:
return
nullptr
;
}
}
void
(
reflection
::
description
::
*
,
collections
::
<
>&
)
{
=
->
();
const
wchar_t
*
=
name
.
();
while
(
reading
)
{
const
wchar_t
*
=
(
reading
,
L"::"
);
if
(
delimiter
)
{
.
(
(
reading
,
(
delimiter
-
reading
)));
reading
=
delimiter
+
2
;
}
else
{
.
(
reading
);
break
;
}
}
}
<
>
GetExpressionFromTypeDescriptor
(
reflection
::
description
::
*
)
{
<
>
;
(
,
fragments
);
<
>
;
FOREACH(WString, fragment, fragments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
fragments
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
fragment
);)
{
if
(!
parentExpr
)
{
auto
=
<
>();
expr
.
fragment
;
parentExpr
expr
;
}
else
{
auto
=
<
>();
expr
parentExpr
;
expr
.
fragment
;
parentExpr
expr
;
}
}
return
parentExpr
;
}
<
>
(
reflection
::
description
::
*
)
{
switch
(
->
())
{
case
::
:
{
<
>
=
(
->
());
if
(
element
)
{
<
>
=
new
;
type
element
;
return
type
;
}
return
0
;
}
case
::
:
{
if
(
->
()->
() ==
::
)
{
return
(
->
());
}
else
{
<
>
=
(
->
());
if
(
element
)
{
<
>
=
new
;
type
element
;
return
type
;
}
return
0
;
}
}
case
::
:
{
<
>
=
(
->
());
if
(
element
)
{
<
>
=
new
;
type
element
;
return
type
;
}
return
0
;
}
case
::
:
{
<
>
;
(
->
(),
fragments
);
<
>
;
FOREACH(WString, fragment, fragments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
fragments
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
fragment
);)
{
if
(!
parentType
)
{
auto
=
<
>();
type
.
fragment
;
parentType
type
;
}
else
{
auto
=
<
>();
type
parentType
;
type
.
fragment
;
parentType
type
;
}
}
return
parentType
;
}
case
::
:
{
if
(
->
()->
() ==
::
)
{
if
(
->
() ==
<
>())
{
if
(
->
() ==
1
)
{
if
(
<
>
=
(
->
(
0
)))
{
<
>
=
new
;
type
elementType
;
return
type
;
}
}
}
else
if
(
->
() ==
<
>())
{
if
(
->
() ==
1
)
{
if
(
<
>
=
(
->
(
0
)))
{
<
>
=
new
;
type
=
::
;
type
valueType
;
return
type
;
}
}
}
else
if
(
->
() ==
<
>())
{
if
(
->
() ==
1
)
{
if
(
<
>
=
(
->
(
0
)))
{
<
>
=
new
;
type
=
::
;
type
valueType
;
return
type
;
}
}
}
else
if
(
->
() ==
<
>())
{
if
(
->
() ==
1
)
{
if
(
<
>
=
(
->
(
0
)))
{
<
>
=
new
;
type
elementType
;
return
type
;
}
}
}
else
if
(
->
() ==
<
>())
{
if
(
->
() ==
2
)
{
if
(
<
>
=
(
->
(
0
)))
if
(
<
>
=
(
->
(
1
)))
{
<
>
=
new
;
type
=
::
;
type
keyType
;
type
valueType
;
return
type
;
}
}
}
else
if
(
->
() ==
<
>())
{
if
(
->
() ==
2
)
{
if
(
<
>
=
(
->
(
0
)))
if
(
<
>
=
(
->
(
1
)))
{
<
>
=
new
;
type
=
::
;
type
keyType
;
type
valueType
;
return
type
;
}
}
}
else
if
(
->
() ==
<
>())
{
if
(
->
() >=
1
)
{
if
(
<
>
=
(
->
(
0
)))
{
<
>
=
new
;
type
(
->
(
0
));
for
(
=
1
;
i
<
->
();
i
++)
{
if
(
<
>
=
(
->
(
i
)))
{
type
.
(
argumentType
);
}
else
{
return
0
;
}
}
return
type
;
}
}
}
}
return
0
;
}
default
:
return
0
;
}
}
class
GetScopeNameFromReferenceTypeVisitor
:
public
,
public
::
{
public
:
*
;
<
>
;
GetScopeNameFromReferenceTypeVisitor
(
*
)
:scope(
)
{
}
<
>
(
*
)
{
->
(
this
);
<
>
=
;
0
;
return
scopeName
;
}
void
(
*
)
override
{
;
switch
(
->
)
{
case
::
:
name
=
L"Void"
;
break
;
case
::
:
name
=
L"Object"
;
break
;
case
::
:
name
=
L"Interface"
;
break
;
case
::
:
#if defined VCZH_64
name = L"Int64";
#else
name
=
L"Int32"
;
#endif
break
;
case
::
:
#if defined VCZH_64
name = L"UInt64";
#else
name
=
L"UInt32"
;
#endif
break
;
case
::
:
name
=
L"Single"
;
break
;
case
::
:
name
=
L"Double"
;
break
;
case
::
:
name
=
L"String"
;
break
;
case
::
:
name
=
L"Char"
;
break
;
case
::
:
name
=
L"Boolean"
;
break
;
default
:
CHECK_FAIL(L"GetScopeNameFromReferenceTypeVisitor::Visit(WfPredefinedType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"GetScopeNameFromReferenceTypeVisitor::Visit(WfPredefinedType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
<
>
=
new
;
ns
.
=
L"system"
;
<
>
=
new
;
type
ns
;
type
.
name
;
type
(
this
);
}
void
(
*
)
override
{
auto
=
->
();
if
(
manager
->
)
{
=
manager
->
.
().
(
->
.
);
if
(
index
!= -
1
)
{
manager
->
.
()
index
];
return
;
}
}
manager
->
.
(
::
TopQualifiedSymbolNotExists
(
,
->
.
));
}
void
(
*
)
override
{
auto
=
->
();
<
>
;
manager
->
(
,
->
.
,
results
);
if
(
results
.
() >
1
)
{
manager
->
.
(
::
(
,
results
,
->
.
));
}
else
if
(
results
.
() ==
1
)
{
if
(
auto
=
results
0
].
)
{
scopeName
;
}
else
{
manager
->
.
(
::
(
,
results
0
]));
}
}
else
{
manager
->
.
(
::
(
,
->
.
));
}
}
void
(
*
)
override
{
CHECK_FAIL(L"GetScopeNameFromReferenceTypeVisitor::Visit(WfRawPointerType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"GetScopeNameFromReferenceTypeVisitor::Visit(WfRawPointerType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
void
(
*
)
override
{
CHECK_FAIL(L"GetScopeNameFromReferenceTypeVisitor::Visit(WfSharedPointerType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"GetScopeNameFromReferenceTypeVisitor::Visit(WfSharedPointerType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
void
(
*
)
override
{
CHECK_FAIL(L"GetScopeNameFromReferenceTypeVisitor::Visit(WfNullableType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"GetScopeNameFromReferenceTypeVisitor::Visit(WfNullableType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
void
(
*
)
override
{
CHECK_FAIL(L"GetScopeNameFromReferenceTypeVisitor::Visit(WfEnumerableType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"GetScopeNameFromReferenceTypeVisitor::Visit(WfEnumerableType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
void
(
*
)
override
{
CHECK_FAIL(L"GetScopeNameFromReferenceTypeVisitor::Visit(WfMapType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"GetScopeNameFromReferenceTypeVisitor::Visit(WfMapType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
void
(
*
)
override
{
CHECK_FAIL(L"GetScopeNameFromReferenceTypeVisitor::Visit(WfObservableListType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"GetScopeNameFromReferenceTypeVisitor::Visit(WfObservableListType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
void
(
*
)
override
{
CHECK_FAIL(L"GetScopeNameFromReferenceTypeVisitor::Visit(WfFunctionType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"GetScopeNameFromReferenceTypeVisitor::Visit(WfFunctionType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
void
(
*
)
override
{
if
(
<
>
=
(
->
.
()))
{
=
scopeName
.
().
(
->
.
);
if
(
index
!= -
1
)
{
scopeName
.
()
index
];
return
;
}
->
()->
.
(
::
(
,
scopeName
,
->
.
));
}
}
static
<
>
(
*
,
*
)
{
return
GetScopeNameFromReferenceTypeVisitor
(
).
(
);
}
};
<
>
GetScopeNameFromReferenceType
(
*
,
<
>
)
{
return
GetScopeNameFromReferenceTypeVisitor
::
(
,
.
());
}
class
CreateTypeInfoFromTypeVisitor
:
public
,
public
::
{
public
:
*
;
<
>
;
CreateTypeInfoFromTypeVisitor
(
*
)
:scope(
)
{
}
<
>
(
*
,
bool
)
{
->
(
this
);
<
>
=
;
0
;
if
(
typeInfo
)
{
auto
=
->
();
switch
(
typeInfo
())
{
case
::
:
case
::
:
switch
(
typeInfo
()->
())
{
case
::
:
case
::
:
case
::
:
break
;
default
:
if
(
typeInfo
() ==
::
)
{
manager
->
.
(
::
RawPointerToNonReferenceType
(
,
typeInfo
.
()));
}
else
{
manager
->
.
(
::
SharedPointerToNonReferenceType
(
,
typeInfo
.
()));
}
}
break
;
case
::
:
switch
(
typeInfo
()->
())
{
case
::
:
case
::
:
case
::
:
case
::
:
break
;
default
:
manager
->
.
(
::
NullableToNonReferenceType
(
,
typeInfo
.
()));
}
break
;
case
::
:
if
(
)
{
switch
(
typeInfo
()->
())
{
case
::
:
case
::
:
case
::
:
case
::
:
case
::
:
break
;
default
:
manager
->
.
(
::
(
,
typeInfo
.
()));
}
}
break
;
case
::
:
if
(
)
{
manager
->
.
(
::
(
,
typeInfo
.
()));
}
break
;
}
}
return
typeInfo
;
}
void
(
*
)
{
if
(
auto
=
GetScopeNameFromReferenceTypeVisitor
::
(
,
))
{
if
(
scopeName
)
{
<
>(
scopeName
,
::
);
}
else
{
->
()->
.
(
::
(
,
scopeName
));
}
}
}
void
(
*
)
override
{
*
=
0
;
switch
(
->
)
{
case
::
:
typeDescriptor
=
description
::
<
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
float
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
double
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
wchar_t
>();
break
;
case
::
:
typeDescriptor
=
description
::
<
bool
>();
break
;
default
:
CHECK_FAIL(L"CreateTypeInfoFromTypeVisitor::Visit(WfPredefinedType*)#Internal error, ValidateTypeStructure function should check correctly.");
do
{
throw
(
L"CreateTypeInfoFromTypeVisitor::Visit(WfPredefinedType*)#Internal error, ValidateTypeStructure function should check correctly."
);}
while
(
0
);
}
if
(
typeDescriptor
)
{
<
>(
typeDescriptor
,
::
);
}
}
void
(
*
)
override
{
(
);
}
void
(
*
)
override
{
(
);
}
void
(
*
)
override
{
if
(
<
>
=
(
->
.
(),
false
))
{
<
>(
element
);
}
}
void
(
*
)
override
{
if
(
<
>
=
(
->
.
(),
false
))
{
<
>(
element
);
}
}
void
(
*
)
override
{
if
(
<
>
=
(
->
.
(),
false
))
{
<
>(
element
);
}
}
void
(
*
)
override
{
if
(
<
>
=
(
->
.
(),
true
))
{
auto
=
<
>(
description
::
<
>(),
::
);
auto
=
<
>(
enumerableTypeInfo
);
genericTypeInfo
(
element
);
<
>(
genericTypeInfo
);
}
}
void
(
*
)
override
{
<
>
,
;
if
(!(
value
(
->
.
(),
true
)))
return
;
if
(
->
)
{
if
(!(
key
(
->
.
(),
true
)))
return
;
}
*
=
nullptr
;
if
(
->
==
::
)
{
if
(
->
)
{
typeDescriptor
=
description
::
<
>();
}
else
{
typeDescriptor
=
description
::
<
>();
}
}
else
{
if
(
->
)
{
typeDescriptor
=
description
::
<
>();
}
else
{
typeDescriptor
=
description
::
<
>();
}
}
auto
=
<
>(
typeDescriptor
,
::
);
auto
=
<
>(
mapTypeInfo
);
if
(
key
)
genericTypeInfo
(
key
);
genericTypeInfo
(
value
);
<
>(
genericTypeInfo
);
}
void
(
*
)
override
{
<
>
;
if
(!(
element
(
->
.
(),
true
)))
return
;
auto
=
description
::
<
>();
auto
=
<
>(
typeDescriptor
,
::
);
auto
=
<
>(
mapTypeInfo
);
genericTypeInfo
(
element
);
<
>(
genericTypeInfo
);
}
void
(
*
)
override
{
if
(
<
>
=
(
->
.
(),
true
))
{
auto
=
<
>(
description
::
<
>(),
::
);
auto
=
<
>(
enumerableTypeInfo
);
genericTypeInfo
(
returnType
);
FOREACH(Ptr<WfType>, argument, node->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
if
(
<
>
=
(
argument
.
(),
true
))
{
genericTypeInfo
(
argumentType
);
}
else
{
return
;
}
}
<
>(
genericTypeInfo
);
}
}
void
(
*
)
override
{
(
);
}
static
<
>
(
*
,
*
,
bool
)
{
return
CreateTypeInfoFromTypeVisitor
(
).
(
,
);
}
};
<
reflection
::
description
::
>
(
*
,
<
>
,
bool
)
{
return
CreateTypeInfoFromTypeVisitor
::
(
,
.
(),
);
}
<
reflection
::
description
::
>
(
reflection
::
description
::
*
)
{
switch
(
->
())
{
case
::
:
return
<
>(
(
->
()));
case
::
:
return
<
>(
(
->
()));
case
::
:
return
<
>(
(
->
()));
case
::
:
return
<
>(
->
(),
->
());
case
::
:
{
auto
=
<
>(
->
());
=
->
();
for
(
=
0
;
i
<
count
;
i
++)
{
impl
(
(
->
(
i
)));
}
return
impl
;
}
default
:;
return
nullptr
;
}
}
<
reflection
::
description
::
>
(
reflection
::
description
::
*
)
{
if
(!
)
return
nullptr
;
return
(
);
}
bool
(
reflection
::
description
::
*
,
reflection
::
description
::
*
,
bool
)
{
*
=
<
>();
bool
=
->
() ==
::
&&
->
() ==
objectType
;
bool
=
->
() ==
::
&&
->
() ==
objectType
;
if
(
fromObject
&&
toObject
)
{
return
true
;
}
else
if
(
fromObject
)
{
return
;
}
else
if
(
toObject
)
{
return
true
;
}
switch
(
->
())
{
case
::
:
switch
(
->
())
{
case
::
:
return
(
->
(),
->
(),
);
case
::
:
return
&&
(
->
(),
->
(),
);
case
::
:
case
::
:
case
::
:
return
false
;
}
break
;
case
::
:
switch
(
->
())
{
case
::
:
return
&&
(
->
(),
->
(),
);
case
::
:
return
(
->
(),
->
(),
);
case
::
:
case
::
:
case
::
:
return
false
;
}
break
;
case
::
:
switch
(
->
())
{
case
::
:
case
::
:
return
false
;
case
::
:
return
(
->
(),
->
(),
);
case
::
:
return
&&
(
->
(),
,
);
case
::
:
return
false
;
}
break
;
case
::
:
switch
(
->
())
{
case
::
:
case
::
:
return
false
;
case
::
:
return
(
,
->
(),
);
case
::
:
{
*
=
->
();
*
=
->
();
bool
= (
fromTd
->
()
::
) ==
::
;
bool
= (
toTd
->
()
::
) ==
::
;
if
(
fromValue
!=
toValue
)
{
return
false
;
}
if
(
fromValue
)
{
if
(
fromTd
==
toTd
)
{
return
true
;
}
else
if
(
fromTd
==
<
>())
{
return
&&
toTd
->
() !=
nullptr
;
}
else
if
(
toTd
==
<
>())
{
return
fromTd
->
() !=
nullptr
;
}
=
(
fromTd
);
=
(
toTd
);
static
[(
)
::
][(
)
::
] = {
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
},
{
0
,
1
,
1
,
1
,
1
,
2
,
2
,
2
,
2
,
1
,
1
,
1
,
0
,
0
,
0
},
{
0
,
2
,
1
,
1
,
1
,
2
,
2
,
2
,
2
,
1
,
1
,
1
,
0
,
0
,
0
},
{
0
,
2
,
2
,
1
,
1
,
2
,
2
,
2
,
2
,
2
,
1
,
1
,
0
,
0
,
0
},
{
0
,
2
,
2
,
2
,
1
,
2
,
2
,
2
,
2
,
2
,
1
,
1
,
0
,
0
,
0
},
{
0
,
2
,
2
,
2
,
2
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
0
,
0
,
0
},
{
0
,
2
,
2
,
2
,
2
,
2
,
1
,
1
,
1
,
1
,
1
,
1
,
0
,
0
,
0
},
{
0
,
2
,
2
,
2
,
2
,
2
,
2
,
1
,
1
,
2
,
1
,
1
,
0
,
0
,
0
},
{
0
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
1
,
2
,
1
,
1
,
2
,
0
,
0
},
{
0
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
1
,
1
,
1
,
0
,
0
,
0
},
{
0
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
1
,
1
,
0
,
0
,
0
},
{
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
1
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
};
=
conversionTable
[(
)
fromFlag
][(
)
toFlag
];
return
conversion
==
1
|| (
&&
conversion
==
2
);
}
else
{
if
(
fromTd
->
(
toTd
))
{
return
true
;
}
if
(
&&
toTd
->
(
fromTd
))
{
return
true
;
}
}
}
break
;
case
::
:
return
&&
(
,
->
(),
);
}
break
;
case
::
:
switch
(
->
())
{
case
::
:
case
::
:
case
::
:
return
false
;
case
::
:
return
(
->
(),
,
);
case
::
:
if
(
)
return
true
;
if
(
->
() !=
->
())
{
return
false
;
}
if
(!
(
->
(),
->
(),
))
return
false
;
for
(
=
0
;
i
<
->
();
i
++)
{
if
(!
(
->
(
i
),
->
(
i
)))
{
return
false
;
}
}
return
true
;
}
break
;
}
return
false
;
}
bool
(
reflection
::
description
::
*
,
reflection
::
description
::
*
)
{
if
(
->
() !=
->
())
{
return
false
;
}
switch
(
->
())
{
case
::
:
case
::
:
case
::
:
return
(
->
(),
->
());
case
::
:
return
->
() ==
->
();
case
::
:
if
(
->
() !=
->
())
{
return
false
;
}
if
(!
(
->
(),
->
()))
return
false
;
for
(
=
0
;
i
<
->
();
i
++)
{
if
(!
(
->
(
i
),
->
(
i
)))
{
return
false
;
}
}
return
true
;
}
return
false
;
}
<
reflection
::
description
::
>
(
<
reflection
::
description
::
>
,
<
reflection
::
description
::
>
)
{
if
(
(
.
(),
.
(),
false
))
{
return
;
}
else
if
(
(
.
(),
.
(),
false
))
{
return
;
}
else
{
return
0
;
}
}
bool
(
reflection
::
description
::
*
)
{
switch
(
->
())
{
case
::
:
case
::
:
case
::
:
return
true
;
case
::
:
return
->
() ==
description
::
<
>();
case
::
:
return
false
;
}
return
false
;
}
<
reflection
::
description
::
>
CreateTypeInfoFromMethodInfo
(
reflection
::
description
::
*
)
{
auto
=
<
>(
description
::
<
>(),
::
);
auto
=
<
>(
elementType
);
genericType
(
(
->
()));
=
->
();
for
(
=
0
;
j
<
parameterCount
;
j
++)
{
genericType
(
(
->
(
j
)->
()));
}
return
<
>(
genericType
);
}
}
}
}