zmike pushed a commit to branch efl-1.22.

http://git.enlightenment.org/core/efl.git/commit/?id=a425a00ecdde0dc3893f5fb076e8745b88b285fd

commit a425a00ecdde0dc3893f5fb076e8745b88b285fd
Author: Xavi Artigas <[email protected]>
Date:   Thu Apr 11 10:38:40 2019 +0200

    mono-docs: Allow embedding external examples
    
    Summary:
    New option added to eolian_gen: -e <dir>
    This specifies a directory to search for examples. If a file is found with 
the
    same name as an EFL C# class (e.g. Efl.Ui.Button.cs) or as an EFL C# method 
or
    property (e.g. Efl.IText.Text.cs, Efl.IText.SetText.cs) its full
    contents will be embedded in the documentation for that class or method 
within
    <example> and <code> tags. This is, in turn, is parsed by DocFX and shown
    in Example boxes in the generated pages.
    If an example file is not found, no examples are embedded for that object.
    If -e is not used, no examples are embedded for any object.
    
    New option added to meson: mono-examples-dir to point to the examples 
directory.
    This directory is then passed to eolian_mono through -e.
    Do not use it (or define it to nothing) to disable example embedding.
    
    No performance drop has been observed because of these extra tests.
    
    Right now examples can only be given for base classes, not for derived ones
    (i.e. Efl.IText.Text but not Efl.Ui.Button.Text). This will be addressed in 
a
    later commit.
    
    Feature
    Depends on D8587
    
    Test Plan:
    Create an examples folder and put some files in it:
    ```
    mkdir /tmp/examples
    echo 'var button = new Efl.Ui.Button();' > /tmp/examples/Efl.Ui.Button.cs
    echo 'button.AutoRepeatEnabled = true;' > 
/tmp/examples/Efl.Ui.IAutorepeat.AutorepeatEnabled.cs
    echo 'button.SetAutoRepeatEnabled(true);' > 
/tmp/examples/Efl.Ui.IAutorepeat.SetAutorepeatEnabled.cs
    ```
    Configure meson to embed examples and build:
    ```
    meson configure -Dmono-examples-dir=/tmp/examples
    ninja
    ```
    Examine the generated efl_ui_button.eo.cs file to see embedded <example> 
tags,
    or run DocFX and bask in the glory of documentation pages with examples:
    ```
    cd doc/docfx
    ./gendoc.sh
    ```
    
    Reviewers: lauromoura, felipealmeida, vitor.sousa, zmike, bu5hm4n
    
    Reviewed By: vitor.sousa
    
    Subscribers: cedric, #reviewers, #committers
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D8592
---
 meson_options.txt                                  |  6 ++++
 src/bin/eolian_mono/eolian/mono/documentation.hh   | 34 ++++++++++++++++++----
 .../eolian_mono/eolian/mono/generation_contexts.hh |  1 +
 src/bin/eolian_mono/eolian_mono.cc                 | 13 +++++++--
 src/bindings/mono/meson.build                      |  1 +
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/meson_options.txt b/meson_options.txt
index 105f4cf9cb..0b6b0bb917 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -323,6 +323,12 @@ option('mono-beta',
   description: 'Flag for enabling @beta Eo methods in the api'
 )
 
+option('mono-examples-dir',
+  type: 'string',
+  value: '',
+  description: 'Directory where eolian_mono will search for examples to embed 
into the documentation'
+)
+
 option('lua-interpreter',
   type: 'combo',
   choices: ['luajit', 'lua'],
diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh 
b/src/bin/eolian_mono/eolian/mono/documentation.hh
index c46cbd4231..0460b5783e 100644
--- a/src/bin/eolian_mono/eolian/mono/documentation.hh
+++ b/src/bin/eolian_mono/eolian/mono/documentation.hh
@@ -313,12 +313,22 @@ struct documentation_generator
    }
 
    template<typename OutputIterator, typename Context>
-   bool generate_tag_example(OutputIterator sink, std::string const& example, 
Context const& context) const
+   bool generate_tag_example(OutputIterator sink, std::string const& 
object_name, Context const& context) const
    {
+      auto options = 
efl::eolian::grammar::context_find_tag<options_context>(context);
+      // Example embedding not requested
+      if (options.examples_dir.empty()) return true;
+      std::string file_name = options.examples_dir + object_name + ".cs";
+      std::ifstream exfile(file_name);
+      // There is no example file for this class or method, just return
+      if (!exfile.good()) return true;
+      std::stringstream example_buff;
+      example_buff << exfile.rdbuf();
+
       if (!as_generator(scope_tab(scope_size) << "/// ").generate(sink, 
attributes::unused, context)) return false;
       if (!generate_opening_tag(sink, "example", context)) return false;
       if (!generate_opening_tag(sink, "code", context)) return false;
-      if (!generate_escaped_content(sink, example, context)) return false;
+      if (!generate_escaped_content(sink, example_buff.str(), context)) return 
false;
       if (!generate_closing_tag(sink, "code", context)) return false;
       if (!generate_closing_tag(sink, "example", context)) return false;
       return as_generator("\n").generate(sink, attributes::unused, context);
@@ -331,6 +341,15 @@ struct documentation_generator
        return generate(sink, attr.documentation, context);
    }
 
+   template<typename OutputIterator, typename Context>
+   bool generate(OutputIterator sink, attributes::klass_def const& klass, 
Context const& context) const
+   {
+       if (!generate(sink, klass.documentation, context)) return false;
+
+       std::string klass_name = 
name_helpers::klass_full_concrete_or_interface_name(klass);
+       return generate_tag_example(sink, klass_name, context);
+   }
+
    template<typename OutputIterator, typename Context>
    bool generate(OutputIterator sink, attributes::property_def const& prop, 
Context const& context) const
    {
@@ -343,9 +362,12 @@ struct documentation_generator
        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
-       else return true;
+       if (!text.empty())
+         if (!generate_tag_value(sink, text, context)) return false;
 
-       return generate_tag_value(sink, text, context);
+       std::string managed_name = 
name_helpers::klass_full_concrete_or_interface_name(prop.klass);
+       managed_name += "." + name_helpers::property_managed_name(prop);
+       return generate_tag_example(sink, managed_name, context);
    }
 
    template<typename OutputIterator, typename Context>
@@ -381,7 +403,7 @@ struct documentation_generator
        if (!generate_tag_return(sink, func.return_documentation.full_text, 
context))
          return false;
 
-       return true;
+       return generate_tag_example(sink, function_conversion(func), context);
    }
 
    template<typename OutputIterator, typename Context>
@@ -397,7 +419,7 @@ struct documentation_generator
        if (!generate_tag_return(sink, func.return_documentation.full_text, 
context))
          return false;
 
-       return true;
+       return generate_tag_example(sink, function_conversion(func), context);
    }
 
    template<typename OutputIterator, typename Context>
diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh 
b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
index 25ac3098fb..ff6c0391ba 100644
--- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
+++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
@@ -78,6 +78,7 @@ struct eolian_state_context {
 
 struct options_context {
     bool want_beta;
+    std::string examples_dir;
 };
 
 }
diff --git a/src/bin/eolian_mono/eolian_mono.cc 
b/src/bin/eolian_mono/eolian_mono.cc
index 0fcc63fa42..8f24f762f0 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -43,6 +43,7 @@ struct options_type
    std::vector<std::string> include_dirs;
    std::string in_file;
    std::string out_file;
+   std::string examples_dir;
    std::string dllimport;
    mutable Eolian_State* state;
    mutable Eolian_Unit const* unit;
@@ -145,7 +146,8 @@ run(options_type const& opts)
 
    auto context = context_add_tag(eolian_mono::indentation_context{0},
                   
context_add_tag(eolian_mono::eolian_state_context{opts.state},
-                  context_add_tag(eolian_mono::options_context{opts.want_beta},
+                  context_add_tag(eolian_mono::options_context{opts.want_beta,
+                                                               
opts.examples_dir},
                   context_add_tag(eolian_mono::library_context{opts.dllimport,
                                                                opts.v_major,
                                                                opts.v_minor,
@@ -294,6 +296,7 @@ _usage(const char *progname)
      << "  -r, --recurse           Recurse input directories loading .eo 
files." << std::endl
      << "  -v, --version           Print the version." << std::endl
      << "  -b, --beta              Enable @beta methods." << std::endl
+     << "  -e, --example-dir <dir> Folder to search for example files." << 
std::endl
      << "  -h, --help              Print this help." << std::endl;
    exit(EXIT_FAILURE);
 }
@@ -324,9 +327,10 @@ opts_get(int argc, char **argv)
        { "vmin", required_argument, 0, 'm' },
        { "references", required_argument, 0, 'r'},
        { "beta", no_argument, 0, 'b'},
+       { "example-dir", required_argument, 0,  'e' },
        { 0,           0,                 0,   0  }
      };
-   const char* options = "I:D:o:c:M:m:ar:vhb";
+   const char* options = "I:D:o:c:M:m:ar:vhbe:";
 
    int c, idx;
    while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
@@ -382,6 +386,11 @@ opts_get(int argc, char **argv)
           {
              opts.want_beta = true;
           }
+        else if (c == 'e')
+          {
+             opts.examples_dir = optarg;
+             if (!opts.examples_dir.empty() && opts.examples_dir.back() != 
'/') opts.examples_dir += "/";
+          }
      }
    if (optind == argc-1)
      {
diff --git a/src/bindings/mono/meson.build b/src/bindings/mono/meson.build
index dc2c856404..e7c5e00d9a 100644
--- a/src/bindings/mono/meson.build
+++ b/src/bindings/mono/meson.build
@@ -127,6 +127,7 @@ foreach lib : mono_sublibs
             command : [eolian_mono_gen, beta_option, '-I', 
meson.current_source_dir(), eolian_include_directories,
                                        '--dllimport', package_name,
                                        '-o', 
join_paths(meson.current_build_dir(), mono_gen_file + '.cs'),
+                                       '-e', get_option('mono-examples-dir'),
                                        '@INPUT@'])
         endif
       endforeach

-- 


Reply via email to