changeset 32892:80d3a6abfc4d stable

improve capture of classdef and classdef method doc strings * lex.h, lex.ll (lexical_feedback::m_classdef_help_text): New data member. (lexical_feedback::lexical_feedback): Initialize it. (lexical_feedback::reset): Reset it to the empty string. * parse.h, oct-parse.yy (function): Also capture comments that appear just before the function body. (base_parser::make_function): New argument ot accept these comments. Maybe capture comments inside a classdef ctor or method as help text. (CLASSDEF): Transfer lexer.m_help_text to lexer.m_classdef_help. (classdef): Also capture comments that appear just before the class body and use the first block of them as classdef help if it is not already set. (base_parser::make_classdef): Pass m_lexer.m_classdef_help_text to tree_classdef ctor then set m_lexer.m_classdef_help_text the empty string. (properties_beg, methods_beg, events_beg, enumeration_beg): Set lexer.m_help_text to the empty string. * pt-classdef.h (tree_classdef::m_help_text): New data member. (tree_classdef::tree_classdef): Initialize it. (tree_classdef::doc_string): Return it instead of m_element_list->doc_string ().
author John W. Eaton <jwe@octave.org>
date Wed, 31 Jan 2024 23:19:10 -0500
parents ff1d5873f805
children 2faec354b977
files libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.yy libinterp/parse-tree/parse.h libinterp/parse-tree/pt-classdef.h
diffstat 5 files changed, 57 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.h	Wed Jan 31 17:28:04 2024 -0500
+++ b/libinterp/parse-tree/lex.h	Wed Jan 31 23:19:10 2024 -0500
@@ -303,6 +303,7 @@
       m_string_text (),
       m_current_input_line (),
       m_comment_text (),
+      m_classdef_help_text (),
       m_help_text (),
       m_function_text (),
       m_fcn_file_name (),
@@ -479,6 +480,9 @@
   // The current comment text.
   std::string m_comment_text;
 
+  // The current classdef help text.
+  std::string m_classdef_help_text;
+
   // The current help text.
   std::string m_help_text;
 
--- a/libinterp/parse-tree/lex.ll	Wed Jan 31 17:28:04 2024 -0500
+++ b/libinterp/parse-tree/lex.ll	Wed Jan 31 23:19:10 2024 -0500
@@ -2205,6 +2205,7 @@
     m_string_text = "";
     m_current_input_line = "";
     m_comment_text = "";
+    m_classdef_help_text = "";
     m_help_text = "";
     m_function_text = "";
     m_fcn_file_name = "";
--- a/libinterp/parse-tree/oct-parse.yy	Wed Jan 31 17:28:04 2024 -0500
+++ b/libinterp/parse-tree/oct-parse.yy	Wed Jan 31 23:19:10 2024 -0500
@@ -1652,19 +1652,17 @@
                   }
                 ;
 
-function        : function_beg stash_comment fcn_name
-                  opt_param_list opt_sep function_body function_end
+function        : function_beg stash_comment fcn_name opt_param_list opt_sep stash_comment function_body function_end
                   {
                     OCTAVE_YYUSE ($5);
 
-                    $$ = parser.make_function ($1, nullptr, $3, $4, $6, $7, $2);
-                  }
-                | function_beg stash_comment return_list '=' fcn_name
-                  opt_param_list opt_sep function_body function_end
+                    $$ = parser.make_function ($1, nullptr, $3, $4, $7, $8, $2, $6);
+                  }
+                | function_beg stash_comment return_list '=' fcn_name opt_param_list opt_sep stash_comment function_body function_end
                   {
                     OCTAVE_YYUSE ($4, $7);
 
-                    $$ = parser.make_function ($1, $3, $5, $6, $8, $9, $2);
+                    $$ = parser.make_function ($1, $3, $5, $6, $9, $10, $2, $8);
                   }
                 ;
 
@@ -1834,6 +1832,9 @@
                         YYABORT;
                       }
 
+                    lexer.m_classdef_help_text = lexer.m_help_text;
+                    lexer.m_help_text = "";
+
                     // Create invalid parent scope.
                     lexer.m_symtab_context.push (octave::symbol_scope::anonymous ());
                     lexer.m_parsing_classdef = true;
@@ -1844,19 +1845,25 @@
                   }
                 ;
 
-classdef        : classdef_beg stash_comment attr_list identifier opt_sep superclass_list class_body END
-                  {
-                    OCTAVE_YYUSE ($5);
-
-                    octave::comment_list *lc = $2;
+classdef        : classdef_beg attr_list identifier opt_sep stash_comment superclass_list stash_comment class_body END
+                  {
+                    OCTAVE_YYUSE ($4);
+
+                    octave::comment_list *lc = $5;
                     octave::comment_list *tc = lexer.get_comment ();
 
+                    if (lexer.m_classdef_help_text.empty () && $7 && ! $7->empty ())
+                      {
+                        const octave::comment_elt& elt = $7->front ();
+                        lexer.m_classdef_help_text = elt.text ();
+                      }
+
                     lexer.m_parsing_classdef = false;
 
-                    if (! ($$ = parser.make_classdef ($1, $3, $4, $6, $7, $8,
+                    if (! ($$ = parser.make_classdef ($1, $2, $3, $6, $8, $9,
                                                       lc, tc)))
                       {
-                        // make_classdef deleted $3, $4, $6, $7, LC, and
+                        // make_classdef deleted $2, $3, $6, $8, LC, and
                         // TC.
                         YYABORT;
                       }
@@ -2010,6 +2017,8 @@
 
 properties_beg  : PROPERTIES
                   {
+                    lexer.m_help_text = "";
+
                     lexer.m_classdef_element_names_are_keywords = false;
                     $$ = $1;
                   }
@@ -2086,6 +2095,8 @@
 
 methods_beg     : METHODS
                   {
+                    lexer.m_help_text = "";
+
                     lexer.m_classdef_element_names_are_keywords = false;
                     $$ = $1;
                   }
@@ -2170,6 +2181,8 @@
 
 events_beg      : EVENTS
                   {
+                    lexer.m_help_text = "";
+
                     lexer.m_classdef_element_names_are_keywords = false;
                     $$ = $1;
                   }
@@ -2222,6 +2235,8 @@
 
 enumeration_beg : ENUMERATION
                   {
+                    lexer.m_help_text = "";
+
                     lexer.m_classdef_element_names_are_keywords = false;
                     $$ = $1;
                   }
@@ -3948,8 +3963,19 @@
                               tree_parameter_list *param_list,
                               tree_statement_list *body,
                               tree_statement *end_fcn_stmt,
-                              comment_list *lc)
-  {
+                              comment_list *lc, comment_list *bc)
+  {
+    // If we are looking at a classdef method and there is a comment
+    // prior to the function keyword and another after, choose the one
+    // inside the function definition for compatibility with Matlab.
+
+    if (m_lexer.m_parsing_classdef && ! m_lexer.m_help_text.empty () && bc && ! bc->empty ())
+      {
+        const octave::comment_elt& elt = bc->front ();
+        m_lexer.m_help_text = elt.text ();
+      }
+
+
     int l = fcn_tok->line ();
     int c = fcn_tok->column ();
 
@@ -4378,8 +4404,11 @@
               body = new tree_classdef_body ();
 
             retval = new tree_classdef (m_lexer.m_symtab_context.curr_scope (),
+                                        m_lexer.m_classdef_help_text,
                                         a, id, sc, body, lc, tc,
                                         m_curr_package_name, full_name, l, c);
+
+            m_lexer.m_classdef_help_text = "";
           }
         else
           {
--- a/libinterp/parse-tree/parse.h	Wed Jan 31 17:28:04 2024 -0500
+++ b/libinterp/parse-tree/parse.h	Wed Jan 31 23:19:10 2024 -0500
@@ -389,7 +389,7 @@
   make_function (token *fcn_tok, tree_parameter_list *ret_list,
                  tree_identifier *id, tree_parameter_list *param_list,
                  tree_statement_list *body, tree_statement *end_fcn_stmt,
-                 comment_list *lc);
+                 comment_list *lc, comment_list *bc);
 
   // Begin defining a function.
   OCTINTERP_API octave_user_function *
--- a/libinterp/parse-tree/pt-classdef.h	Wed Jan 31 17:28:04 2024 -0500
+++ b/libinterp/parse-tree/pt-classdef.h	Wed Jan 31 23:19:10 2024 -0500
@@ -679,13 +679,14 @@
 {
 public:
 
-  tree_classdef (const symbol_scope& scope,
+  tree_classdef (const symbol_scope& scope, const std::string& help_text,
                  tree_classdef_attribute_list *a, tree_identifier *i,
                  tree_classdef_superclass_list *sc,
                  tree_classdef_body *b, comment_list *lc,
                  comment_list *tc, const std::string& pn = "",
                  const std::string& fn = "", int l = -1, int c = -1)
-    : tree_command (l, c), m_scope (scope), m_attr_list (a), m_id (i),
+    : tree_command (l, c), m_scope (scope), m_help_text (help_text),
+      m_attr_list (a), m_id (i),
       m_supclass_list (sc), m_element_list (b), m_lead_comm (lc),
       m_trail_comm (tc), m_pack_name (pn), m_file_name (fn)
   { }
@@ -726,7 +727,7 @@
 
   std::string doc_string () const
   {
-    return m_element_list ? m_element_list->doc_string () : "";
+    return m_help_text;
   }
 
   void accept (tree_walker& tw)
@@ -742,6 +743,8 @@
 
   symbol_scope m_scope;
 
+  std::string m_help_text;
+
   tree_classdef_attribute_list *m_attr_list;
 
   tree_identifier *m_id;