#include "GuiInstanceLoader_WorkflowCodegen.h"
#include "../GuiInstanceLocalizedStrings.h"
namespace
{
namespace
{
using
namespace
reflection
::
description
;
using
namespace
collections
;
using
namespace
parsing
;
using
namespace
workflow
::
analyzer
;
::
Workflow_AdjustPropertySearchType
(
types
::
&
,
::
,
)
{
if
(
.
.
() ==
.
)
{
if
(
auto
=
.
())
{
=
propTd
->
GetBaseTypeDescriptorCount
();
for
(
=
0
;
i
<
baseCount
;
i
++)
{
auto
=
propTd
->
(
i
);
if
(
auto
=
baseTd
->
())
{
if
(
ctorGroup
->
() ==
1
)
{
auto
=
ctorGroup
->
(
0
);
auto
=
.
();
auto
=
L"<ctor-parameter>"
+
propertyName
;
=
ctor
->
();
for
(
=
0
;
j
<
paramCount
;
j
++)
{
auto
=
ctor
->
(
j
);
if
(
parameterInfo
->
() ==
ctorArgumentName
)
{
if
(
baseTd
->
(
propertyName
,
false
))
{
.
(
ctor
->
());
.
::
(
baseTd
->
());
return
;
}
break
;
}
}
}
}
}
}
}
return
;
}
bool
Workflow_GetPropertyTypes
(
&
,
types
::
&
,
*
,
::
,
,
<
::
>
,
collections
::
<
types
::
>&
,
::
&
)
{
Workflow_AdjustPropertySearchType
(
,
,
);
bool
=
false
;
::
(
,
);
=
L"Precompile: Property \""
+
propertyInfo
.
.
() +
L"\" of type \""
+
.
.
() +
L"\""
;
{
auto
=
;
while
(
currentLoader
)
{
if
(
auto
=
currentLoader
->
(
propertyInfo
))
{
if
(
propertyTypeInfo
==
::
)
{
.
(
({
.
},
,
+
L" is not supported."
));
reportedNotSupported
=
true
;
break
;
}
else
{
types
::
;
resolving
.
=
currentLoader
;
resolving
.
propertyInfo
;
resolving
.
propertyTypeInfo
;
.
(
resolving
);
if
(
==
::
)
{
break
;
}
}
if
(
propertyTypeInfo
==
::
)
{
break
;
}
}
currentLoader
=
()->
(
currentLoader
);
}
}
if
(
.
() ==
0
)
{
if
(!
reportedNotSupported
)
{
.
(
({
.
},
,
+
L" does not exist."
));
}
return
false
;
}
else
{
return
true
;
}
}
class
WorkflowReferenceNamesVisitor
:
public
,
public
::
{
public
:
GuiResourcePrecompileContext
&
;
types
::
&
;
&
;
::
&
;
<
types
::
>&
candidatePropertyTypeInfos
;
::
;
= -
1
;
WorkflowReferenceNamesVisitor
(
GuiResourcePrecompileContext
&
,
types
::
&
,
<
types
::
>&
_candidatePropertyTypeInfos
,
&
,
::
&
)
:precompileContext(
)
, resolvingResult(
)
, candidatePropertyTypeInfos(
_candidatePropertyTypeInfos
)
, generatedNameCount(
)
, errors(
)
{
}
void
(
*
)
override
{
if
(
== -
1
)
{
=
0
;
}
auto
=
candidatePropertyTypeInfos
];
auto
=
candidate
.
;
*
=
nullptr
;
{
auto
=
candidate
.
0
];
if
(
auto
=
()->
(
propertyInfo
,
typeInfo
.
()))
{
td
=
deserializer
->
(
propertyInfo
,
typeInfo
.
())->
();
}
else
{
td
=
typeInfo
();
}
}
if
(
auto
=
td
->
())
{
;
if
(
st
->
(
->
text
,
value
))
{
.
.
(
,
candidate
);
}
else
{
auto
=
L"Precompile: Property \""
+
propertyInfo
.
.
()
+
L"\" of type \""
+
propertyInfo
.
.
.
()
+
L"\" does not accept a value of text \""
+
->
text
+
L"\" because it is not in a correct format of the serializable type \""
+
td
->
()
+
L"\"."
;
.
(
({
.
},
->
,
error
));
}
}
else
{
switch
(
td
->
())
{
case
::
:
case
::
:
case
::
:
{
if
(
auto
=
(
,
td
, {
.
},
->
text
,
->
,
))
{
.
.
(
,
candidate
);
}
}
break
;
default
:
{
auto
=
L"Precompile: Property \""
+
propertyInfo
.
.
()
+
L"\" of type \""
+
propertyInfo
.
.
.
()
+
L"\" does not accept a value of text \""
+
->
text
+
L"\" because its type \""
+
td
->
()
+
L"\" is not serializable."
;
.
(
({
.
},
->
,
error
));
}
}
}
}
void
(
*
)
override
{
if
(
candidatePropertyTypeInfos
.
() >
0
)
{
.
.
(
,
candidatePropertyTypeInfos
]);
}
bool
= (
.
()->
()
::
) !=
::
;
if
(
->
==
::
)
{
if
(
isReferenceType
)
{
auto
=
::
(
L"<precompile>"
+
(
++));
->
=
name
;
.
.
(
name
,
);
}
}
else
if
(
.
.
().
(
->
))
{
auto
=
L"Precompile: Referece name \""
+
->
.
()
+
L"\" conflict with an existing named object."
;
.
(
({
.
},
->
,
error
));
}
else
if
(!
isReferenceType
)
{
auto
=
L"Precompile: Reference name \""
+
->
.
()
+
L"\" cannot be added to a non-reference instance of type \""
+
.
.
()
+
L"\"."
;
.
(
({
.
},
->
,
error
));
}
else
{
.
.
(
->
);
.
.
(
->
,
);
}
auto
=
()->
(
.
);
FOREACH_INDEXER(Ptr<GuiAttSetterRepr::SetterValue>, setter, index, repr->setters.Values())
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__
.
(
setter
);
index
++)
{
<
types
::
>
;
auto
=
->
.
()
index
];
;
if
(
Workflow_GetPropertyTypes
(
errorPrefix
,
,
loader
,
,
prop
,
setter
,
possibleInfos
,
))
{
if
(
setter
==
::
)
{
FOREACH(Ptr<GuiValueRepr>, value, setter->values)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
setter
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
value
);)
{
WorkflowReferenceNamesVisitor
(
,
,
possibleInfos
,
,
);
value
(&
visitor
);
}
}
else
if
(
setter
==
::
)
{
if
(
possibleInfos
0
].
==
::
)
{
auto
=
dynamic_cast
<
*>(
setter
0
].
());
WorkflowReferenceNamesVisitor
(
,
,
possibleInfos
,
,
);
auto
=
possibleInfos
0
].
0
];
visitor
.
=
0
;
visitor
.
.
::
(
typeInfo
()->
());
visitor
.
.
typeInfo
;
setTarget
->
(&
visitor
);
}
else
{
.
(
({
.
},
setter
,
L"[INTERNAL-ERROR] "
+
errorPrefix
+
L" does not support the \"-set\" binding."
));
}
}
else
if
(
setter
!=
::
)
{
auto
=
()->
(
setter
);
if
(
binder
)
{
if
(
possibleInfos
0
].
==
::
)
{
if
(
possibleInfos
0
].
==
::
)
{
.
(
({
.
},
setter
,
errorPrefix
+
L" cannot be assigned using binding \"-"
+
setter
.
() +
L"\". Because it is a non-bindable constructor argument."
));
}
else
if
(!
binder
->
ApplicableToConstructorArgument
())
{
.
(
({
.
},
setter
,
errorPrefix
+
L" cannot be assigned using binding \"-"
+
setter
.
() +
L"\". Because it is a constructor argument, and this binding does not apply to any constructor argument."
));
}
}
}
else
{
.
(
({
.
},
setter
,
errorPrefix
+
L" cannot be assigned using an unexisting binding \"-"
+
setter
.
() +
L"\"."
));
}
if
(
setter
.
() ==
1
&&
setter
0
].
<
>())
{
.
.
(
setter
0
].
(),
possibleInfos
0
]);
}
else
{
.
(
({
.
},
setter
,
L"Precompile: Binder \""
+
setter
.
() +
L"\" requires the text value of property \""
+
prop
.
() +
L"\"."
));
}
}
}
}
<
,
*>
;
(
properties
,
(
->
)
.SelectMany([=](
<
,
<
::
>>
)
{
return
(
item
.
)
.Where([=](
<
>
)
{
return
.
.
().
(
value
.
());
})
.Select([=](
<
>
)
{
auto
=
.
value
.
()].
;
return
<
,
*>(
item
.
,
loader
);
});
})
.Distinct()
);
if
(
.
.
() !=
)
{
<
>
;
{
auto
=
loader
;
while
(
currentLoader
)
{
currentLoader
->
(
,
requiredProps
);
currentLoader
=
()->
(
currentLoader
);
}
}
FOREACH(GlobalStringKey, prop, From(requiredProps).Distinct())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
(
requiredProps
).Distinct());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
prop
);)
{
if
(!
properties
.
().
(
prop
))
{
<
>
;
{
auto
=
loader
;
while
(
currentLoader
&& !
info
)
{
info
currentLoader
->
({
,
prop
});
currentLoader
=
()->
(
currentLoader
);
}
}
.
(
({
.
},
->
,
L"Precompile: Missing required "
+
(
info
==
::
?
L"constructor argument"
:
L"property"
) +
L" \""
+
prop
.
() +
L"\" of type \""
+
.
.
() +
L"\"."
));
}
}
}
while
(
properties
.
() >
0
)
{
auto
=
properties
.
()
0
];
auto
=
properties
.
(
0
)
0
];
::
(
,
prop
);
<
>
;
loader
->
(
propertyInfo
,
pairProps
);
if
(
pairProps
.
() >
0
)
{
<
>
;
FOREACH(GlobalStringKey, key, pairProps)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
pairProps
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
key
);)
{
if
(!
properties
.
(
key
,
loader
))
{
missingProps
.
(
key
);
}
}
if
(
missingProps
.
() >
0
)
{
=
L"Precompile: When you assign to property \""
+
prop
.
()
+
L"\" of type \""
+
.
.
()
+
L"\", the following missing properties are required: "
;
FOREACH_INDEXER(GlobalStringKey, key, index, missingProps)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
missingProps
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
if
(
bool
=
true
)
for
(
=
0
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
key
);
index
++)
{
if
(
index
>
0
)
error
+=
L", "
;
error
+=
L"\""
+
key
.
() +
L"\""
;
}
error
+=
L"."
;
.
(
({
.
},
->
prop
]
,
error
));
}
FOREACH(GlobalStringKey, key, pairProps)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
pairProps
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
key
);)
{
properties
.
(
key
,
loader
);
}
}
else
{
properties
.
(
prop
,
loader
);
}
}
FOREACH(Ptr<GuiAttSetterRepr::EventValue>, handler, repr->eventHandlers.Values())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
::
>>&
= ::
vl
::
collections
::
(
->
.
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
::
>
;
__foreach_iterator__
.
(
handler
);)
{
if
(
handler
!=
::
)
{
auto
=
()->
(
handler
);
if
(!
binder
)
{
.
(
({
.
},
handler
,
L"The appropriate IGuiInstanceEventBinder of binding \"-"
+
handler
.
() +
L"\" cannot be found."
));
}
}
}
}
void
(
*
)
override
{
bool
=
false
;
bool
=
->
==
::
&&
->
==
::
;
if
(
inferType
)
{
if
(
candidatePropertyTypeInfos
.
() ==
1
)
{
auto
=
candidatePropertyTypeInfos
0
].
;
if
(
info
.
() ==
1
)
{
auto
=
info
0
];
.
::
(
typeInfo
()->
());
.
typeInfo
;
}
}
}
else
{
if
(
==
.
.
())
{
auto
=
::
(
.
);
if
(
auto
=
()->
(
fullName
))
{
.
fullName
;
.
typeInfo
;
found
=
true
;
}
}
if
(!
found
)
{
auto
=
FindInstanceLoadingSource
(
.
,
);
.
source
.
;
.
()->
(
source
.
);
}
}
if
(
.
)
{
static
const
wchar_t
[] =
L"<ctor-parameter>"
;
static
const
= (
)
sizeof
(
Prefix
) /
sizeof
(*
Prefix
) -
1
;
auto
=
FindInstanceLoadingSource
(
.
,
);
if
(
auto
=
description
::
(
source
.
.
()))
{
if
(
auto
=
baseTd
->
())
{
if
(
ctorGroup
->
() ==
1
)
{
auto
=
ctorGroup
->
(
0
);
=
ctor
->
();
for
(
=
0
;
i
<
paramCount
;
i
++)
{
auto
=
ctor
->
(
i
);
auto
=
parameterInfo
->
();
if
(
ctorArg
.
() >
PrefixLength
&&
ctorArg
.
(
PrefixLength
) ==
Prefix
)
{
auto
=
ctorArg
.
(
ctorArg
.
() -
PrefixLength
);
if
(
baseTd
->
(
propName
,
false
))
{
if
(!
->
.
().
(
::
(
propName
)))
{
.
(
({
.
},
->
,
L"Precompile: Missing required property \""
+
propName
+
L"\" of type \""
+
.
.
() +
L"\" for its base type \""
+
baseTd
->
() +
L"\"."
));
}
}
}
}
}
}
}
}
if
(
.
)
{
for
(
=
0
;
i
<
candidatePropertyTypeInfos
.
();
i
++)
{
const
auto
&
=
candidatePropertyTypeInfos
i
].
;
for
(
=
0
;
j
<
typeInfos
.
();
j
++)
{
if
(
.
()->
(
typeInfos
j
]
()))
{
=
i
;
goto
FINISH_MATCHING;
}
}
}
FINISH_MATCHING:
if
(
== -
1
&&
candidatePropertyTypeInfos
.
() >
0
)
{
auto
=
candidatePropertyTypeInfos
0
].
;
auto
=
L"Precompile: Property \""
+
propertyInfo
.
.
()
+
L"\" of type \""
+
propertyInfo
.
.
.
()
+
L"\" does not accept a value of type \""
+
.
.
()
+
L"\" because it only accepts value of the following types: "
;
for
(
=
0
;
i
<
candidatePropertyTypeInfos
.
();
i
++)
{
const
auto
&
=
candidatePropertyTypeInfos
i
].
;
for
(
=
0
;
j
<
typeInfos
.
();
j
++)
{
if
(
i
!=
0
||
j
!=
0
)
{
error
+=
L", "
;
}
error
+=
L"\""
+
typeInfos
j
]
() +
L"\""
;
}
}
error
+=
L"."
;
.
(
({
.
},
->
,
error
));
}
else
{
if
(
->
.
() ==
1
&&
->
.
()[
0
] ==
::
)
{
auto
=
->
.
()
0
];
if
(
setter
.
() ==
1
)
{
if
(
auto
=
setter
0
].
<
>())
{
if
(
candidatePropertyTypeInfos
.
() ==
0
)
{
.
(
({
.
},
->
,
L"Precompile: Type \""
+
.
.
() +
L"\" cannot be used to create an instance."
));
}
else
{
(
text
.
());
auto
=
.
.
().
(
text
.
());
if
(
index
!= -
1
)
{
auto
=
.
.
()
index
];
.
.
(
text
.
());
.
.
(
,
value
);
}
}
return
;
}
}
}
if
(
.
.
() !=
)
{
auto
=
()->
(
.
);
while
(
loader
)
{
if
(
loader
->
(
))
{
break
;
}
loader
=
()->
(
loader
);
}
if
(
loader
)
{
if
(
==
.
.
())
{
<
>
;
loader
->
(
,
propertyNames
);
for
(
=
propertyNames
.
() -
1
;
i
>=
0
;
i
--)
{
auto
=
loader
->
({
,
propertyNames
i
] });
if
(!
info
||
info
==
::
)
{
propertyNames
.
(
i
);
}
}
if
(
propertyNames
.
() ==
1
)
{
if
(
propertyNames
[
0
] !=
::
)
{
.
(
({
.
},
->
,
L"Precompile: Type \""
+
.
.
() +
L"\" cannot be used to create a root instance, because its only constructor parameter is not for a the control template."
));
}
}
else
if
(
propertyNames
.
() >
1
)
{
.
(
({
.
},
->
,
L"Precompile: Type \""
+
.
.
() +
L"\" cannot be used to create a root instance, because it has more than one constructor parameters. A root instance type can only have one constructor parameter, which is for the control template."
));
}
}
}
else
{
.
(
({
.
},
->
,
L"Precompile: Type \""
+
.
.
() +
L"\" cannot be used to create an instance."
));
}
}
((
*)
);
}
}
else
{
.
(
({
.
},
->
,
L"[INTERNAL-ERROR] Precompile: Failed to find type \""
+
(
->
==
::
?
->
.
()
:
->
.
() +
L":"
+
->
.
()
) +
L"\"."
));
}
}
};
<
reflection
::
description
::
>
Workflow_GetSuggestedParameterType
(
reflection
::
description
::
*
)
{
auto
=
<
>(
,
::
);
if
((
->
()
::
) !=
::
)
{
bool
=
false
;
bool
=
false
;
if
(
auto
=
->
())
{
=
ctorGroup
->
();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
ctorGroup
->
(
i
)->
();
switch
(
returnType
->
())
{
case
::
:
isRaw
=
true
;
break
;
case
::
:
isShared
=
true
;
break
;
default
:;
}
}
}
if
(!
isShared
&& !
isRaw
)
{
return
<
>(
elementType
);
}
else
if
(
isShared
)
{
return
<
>(
elementType
);
}
else
{
return
<
>(
elementType
);
}
}
else
{
return
elementType
;
}
}
::
Workflow_CollectReferences
(
GuiResourcePrecompileContext
&
,
types
::
&
,
::
&
)
{
FOREACH(Ptr<GuiInstanceParameter>, parameter, resolvingResult.context->parameters)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
.
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
parameter
);)
{
auto
=
(
parameter
.
());
if
(!
type
)
{
.
(
({
.
},
parameter
,
L"Precompile: Cannot find type \""
+
parameter
.
() +
L"\"."
));
}
else
if
(
.
.
().
(
parameter
))
{
.
(
({
.
},
parameter
,
L"[INTERNAL-ERROR] Precompile: Parameter \""
+
parameter
.
() +
L"\" conflict with an existing named object."
));
}
else
{
auto
=
Workflow_GetSuggestedParameterType
(
type
);
.
.
(
parameter
, {
::
(
type
->
()),
referenceType
});
}
}
<
types
::
>
;
=
0
;
WorkflowReferenceNamesVisitor
(
,
,
infos
,
generatedNameCount
,
);
.
(&
visitor
);
return
visitor
.
;
}
}
}