csharp: Generating documentation for tuple-value properties.

Adds documentation for tuple-value properties (properties with
multiple values), so the following Eo:

```
@property multi_valued_prop {
   [[ A multi valued property. ]]
   get {}
   set {}
   values {
     prop1: int; [[ Dummy property's first element. ]]
     prop2: int; [[ Dummy property's second element. ]]
   }
}
```

Generates the following documentation:

```
/// <summary>A multi valued property.<br/>
/// Since EFL *current version*.</summary>
/// <value>A tuple containing the following information:
/// <list type="bullet">
/// <item><description><c>prop1</c> (<c>Item0</c>): Dummy property&apos;s first element.</description></item>
/// <item><description><c>prop2</c> (<c>Item1</c>): Dummy property&apos;s second element.</description></item>
/// </list></value>
```

Note: This commit also adds a default separator between tag name and
parameters in `generate_opening_tag`.

Ref T8468.

Differential Revision: https://phab.enlightenment.org/D10889
This commit is contained in:
João Paulo Taylor Ienczak Zanette 2020-01-20 18:42:05 +00:00 committed by Felipe Magno de Almeida
parent 4f3b3a33f5
commit 651517808c
2 changed files with 94 additions and 5 deletions

View File

@ -315,7 +315,9 @@ struct documentation_generator
template<typename OutputIterator, typename Context>
bool generate_opening_tag(OutputIterator sink, std::string const& tag, Context const& context, std::string tag_params = "") const
{
return as_generator("<" << tag << tag_params << ">").generate(sink, attributes::unused, context);
auto tag_separator = tag_params.empty() ? "" : " ";
return as_generator("<" << tag << tag_separator << tag_params << ">").generate(sink, attributes::unused, context);
}
template<typename OutputIterator, typename Context>
@ -461,6 +463,69 @@ struct documentation_generator
return generate_tag_example(sink, klass_name, context);
}
/*! Generates documentation for tuple-value properties.
*
* Example:
*
* A tuple containing the following information:
* <list type="bullet">
* <item><description><c>a</c>: Parameter a.</description></item>
* <item><description><c>b</c>: Parameter b.</description></item>
* </list>
*
* \param index_names If true, tuple items are referenced by their index. If
* false, they are referenced by their names instead.
*/
template<typename OutputIterator, typename Context>
bool generate_tuple_parameters_doc(OutputIterator sink,
std::vector<attributes::parameter_def> const& parameters,
Context const& context,
bool numbered_refs = false) const
{
if (!(as_generator(scope_tab(scope_size) << "/// ")
.generate(sink, attributes::unused, context)
&& as_generator(
"A tuple containing the following information:\n"
<< scope_tab(scope_size) << "/// "
).generate(sink, attributes::unused, context)
&& generate_opening_tag(sink, "list", context, "type=\"bullet\"")
&& as_generator("\n" << scope_tab(scope_size) << "/// ")
.generate(sink, attributes::unused, context)))
return false;
auto i = 0u;
for (auto const& param: parameters)
{
auto name = param.param_name;
if (!(generate_opening_tag(sink, "item", context)
&& generate_opening_tag(sink, "description", context)
&& generate_opening_tag(sink, "c", context)
&& as_generator(name).generate(sink, attributes::unused, context)
&& generate_closing_tag(sink, "c", context)))
return false;
if (numbered_refs && !(
as_generator(" (").generate(sink, attributes::unused, context)
&& generate_opening_tag(sink, "c", context)
&& as_generator("Item" + std::to_string(i)).generate(sink, attributes::unused, context)
&& generate_closing_tag(sink, "c", context)
&& as_generator(")").generate(sink, attributes::unused, context)))
return false;
if (!(generate_escaped_content(sink, ": " + param.documentation.full_text, context)
&& generate_closing_tag(sink, "description", context)
&& generate_closing_tag(sink, "item", context)
&& as_generator("\n" << scope_tab(scope_size) << "/// ")
.generate(sink, attributes::unused, context)))
return false;
++i;
}
return generate_closing_tag(sink, "list", context)
&& as_generator("\n")
.generate(sink, attributes::unused, context);
}
template<typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::property_def const& prop, Context const& context) const
{
@ -483,12 +548,35 @@ struct documentation_generator
text = "";
if (prop.setter.is_engaged())
text = prop.setter->parameters[0].documentation.full_text;
{
if (prop.setter.is_engaged() && prop.setter->values.size() > 1u)
{
if (!(
as_generator(scope_tab(scope_size) << "/// ")
.generate(sink, attributes::unused, context)
&& generate_opening_tag(sink, "value", context)
&& as_generator("\n")
.generate(sink, attributes::unused, context)
&& generate_tuple_parameters_doc(sink, prop.setter->parameters, context, true)
&& as_generator(scope_tab(scope_size) << "/// ")
.generate(sink, attributes::unused, context)
&& generate_closing_tag(sink, "value", context)
&& as_generator("\n")
.generate(sink, attributes::unused, context)
))
return false;
}
else
text = prop.setter->parameters[0].documentation.full_text;
}
else if (prop.getter.is_engaged())
text = prop.getter->return_documentation.full_text;
// If there are no docs at all, do not generate <value> tag
if (!text.empty())
if (!generate_tag_value(sink, text, context)) return false;
if (!generate_tag_value(
sink,
text,
context)) return false;
return generate_all_tag_examples(sink,
name_helpers::klass_full_concrete_or_interface_name(prop.klass),

View File

@ -1576,11 +1576,12 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface {
}
@property multi_valued_prop {
[[ A multi valued property. ]]
get {}
set {}
values {
prop1: int;
prop2: int;
prop1: int; [[ Dummy property's first element. ]]
prop2: int; [[ Dummy property's second element. ]]
}
}