changeset 33230:515c1cc1b45e

display function signature as help text for undocumented functions (bug #65258) * ov-usr-fcn.h, ov-usr-fcn.cc (octave_user_function::signature): New function. * help.cc (get_help_from_fcn): If function is undocumented, set help text to function signature. (help_system::raw_help_for_class): If there is no "." in name, look for class constructor doc string. If no constructor is defined, set help to signature of default constructor.
author John W. Eaton <jwe@octave.org>
date Wed, 20 Mar 2024 23:14:22 -0400
parents d5c5484322d1
children 92ca2f6c6b85
files libinterp/corefcn/help.cc libinterp/octave-value/ov-usr-fcn.cc libinterp/octave-value/ov-usr-fcn.h
diffstat 3 files changed, 57 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/help.cc	Wed Mar 20 08:12:28 2024 +0100
+++ b/libinterp/corefcn/help.cc	Wed Mar 20 23:14:22 2024 -0400
@@ -675,6 +675,20 @@
       help = fcn->doc_string (fcn_nm);
       what = fcn->fcn_file_name ();
 
+      if (help.empty () && ov_fcn.is_user_function ())
+        {
+          octave_user_function *ufcn = ov_fcn.user_function_value ();
+
+          if (ufcn->is_classdef_constructor ())
+            help = "undocumented constructor: ";
+          else if (ufcn->is_classdef_method ())
+            help = "undocumented method: ";
+          else
+            help = "undocumented function: ";
+
+          help += ufcn->signature ();
+        }
+
       if (what.empty ())
         what = fcn->is_user_function () ? "command-line function" : "built-in function";
 
@@ -719,10 +733,23 @@
             }
         }
 
-      // We found a class, but no docstring for it or its constructor.
-      // Create a generic doc string.
-      help = name + " is an undocumented class";
-      what = "class";
+      // No dot in name and class is undocumented.  Look for documented
+      // constructor.
+
+      octave_value ov_meth = cls.get_method (name);
+
+      if (get_help_from_fcn (name, ov_meth, help, what, symbol_found))
+        {
+          what = "constructor";
+          symbol_found = true;
+          return true;
+        }
+
+      // We found a class, but no docstring for it and there is no
+      // constructor explicitly defined.
+
+      help = "default constructor: obj = " + name + "()";
+      what = "constructor";
       symbol_found = true;
       return true;
     }
--- a/libinterp/octave-value/ov-usr-fcn.cc	Wed Mar 20 08:12:28 2024 +0100
+++ b/libinterp/octave-value/ov-usr-fcn.cc	Wed Mar 20 23:14:22 2024 -0400
@@ -235,6 +235,29 @@
   delete m_trail_comm;
 }
 
+std::string
+octave_user_function::signature () const
+{
+  std::ostringstream buf;
+
+  octave::tree_print_code tpc (buf);
+
+  if (m_ret_list)
+    {
+      m_ret_list->accept (tpc);
+      buf << " = ";
+    }
+
+  buf << m_name << " ";
+
+  if (m_param_list)
+    m_param_list->accept (tpc);
+  else
+    buf << " ()";
+
+  return buf.str ();
+}
+
 octave_user_function *
 octave_user_function::define_ret_list (octave::tree_parameter_list *t)
 {
--- a/libinterp/octave-value/ov-usr-fcn.h	Wed Mar 20 08:12:28 2024 +0100
+++ b/libinterp/octave-value/ov-usr-fcn.h	Wed Mar 20 23:14:22 2024 -0400
@@ -210,6 +210,9 @@
 
   ~octave_user_function ();
 
+  // Declared calling form, generated from the parse tree.
+  std::string signature () const;
+
   octave_function * function_value (bool = false) { return this; }
 
   octave_user_function * user_function_value (bool = false) { return this; }