Mercurial > octave
view libinterp/parse-tree/pt-classdef.h @ 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 | 2e484f9f1f18 |
children | 0b5f3219b650 |
line wrap: on
line source
//////////////////////////////////////////////////////////////////////// // // Copyright (C) 2012-2024 The Octave Project Developers // // See the file COPYRIGHT.md in the top-level directory of this // distribution or <https://octave.org/copyright/>. // // This file is part of Octave. // // Octave is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Octave is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Octave; see the file COPYING. If not, see // <https://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////// #if ! defined (octave_tree_classdef_h) #define octave_tree_classdef_h 1 #include "octave-config.h" class octave_value; #include "comment-list.h" #include "pt-cmd.h" #include "pt-exp.h" #include "pt-walk.h" #include "pt-id.h" #include "base-list.h" #include <list> OCTAVE_BEGIN_NAMESPACE(octave) class interpreter; class tree_arg_validation; class tree_superclass_ref : public tree_expression { public: tree_superclass_ref (const std::string& meth, const std::string& cls, int l = -1, int c = -1) : tree_expression (l, c), m_method_name (meth), m_class_name (cls) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_superclass_ref) ~tree_superclass_ref () = default; std::string method_name () const { return m_method_name; } std::string class_name () const { return m_class_name; } tree_superclass_ref * dup (symbol_scope& scope) const; octave_value evaluate (tree_evaluator& tw, int nargout = 1) { octave_value_list retval = evaluate_n (tw, nargout); return retval.length () > 0 ? retval(0) : octave_value (); } octave_value_list evaluate_n (tree_evaluator& tw, int nargout = 1); void accept (tree_walker& tw) { tw.visit_superclass_ref (*this); } private: // The name of the method to call. This is the text before the // "@" and may be of the form "object.method". std::string m_method_name; // The name of the superclass. This is the text after the "@" // and may be of the form "object.method". std::string m_class_name; }; class tree_metaclass_query : public tree_expression { public: tree_metaclass_query (const std::string& cls, int l = -1, int c = -1) : tree_expression (l, c), m_class_name (cls) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_metaclass_query) ~tree_metaclass_query () = default; std::string class_name () const { return m_class_name; } tree_metaclass_query * dup (symbol_scope& scope) const; octave_value evaluate (tree_evaluator&, int nargout = 1); octave_value_list evaluate_n (tree_evaluator& tw, int nargout = 1) { return ovl (evaluate (tw, nargout)); } void accept (tree_walker& tw) { tw.visit_metaclass_query (*this); } private: std::string m_class_name; }; class tree_classdef_attribute { public: tree_classdef_attribute (tree_identifier *i = nullptr, tree_expression *e = nullptr) : m_id (i), m_expr (e), m_neg (false) { } tree_classdef_attribute (tree_identifier *i, bool b) : m_id (i), m_expr (nullptr), m_neg (b) { } OCTAVE_DISABLE_COPY_MOVE (tree_classdef_attribute) ~tree_classdef_attribute () { delete m_id; delete m_expr; } tree_identifier * ident () { return m_id; } tree_expression * expression () { return m_expr; } bool negate () { return m_neg; } void accept (tree_walker& tw) { tw.visit_classdef_attribute (*this); } private: tree_identifier *m_id; tree_expression *m_expr; bool m_neg; }; class tree_classdef_attribute_list : public base_list<tree_classdef_attribute *> { public: tree_classdef_attribute_list () { } tree_classdef_attribute_list (tree_classdef_attribute *a) { append (a); } tree_classdef_attribute_list (const base_list<tree_classdef_attribute *>& a) : base_list<tree_classdef_attribute *> (a) { } OCTAVE_DISABLE_COPY_MOVE (tree_classdef_attribute_list) ~tree_classdef_attribute_list (); void accept (tree_walker& tw) { tw.visit_classdef_attribute_list (*this); } }; class tree_classdef_superclass { public: tree_classdef_superclass (const std::string& cname) : m_cls_name (cname) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_superclass) ~tree_classdef_superclass () = default; std::string class_name () { return m_cls_name; } void accept (tree_walker& tw) { tw.visit_classdef_superclass (*this); } private: std::string m_cls_name; }; class tree_classdef_superclass_list : public base_list<tree_classdef_superclass *> { public: tree_classdef_superclass_list () { } tree_classdef_superclass_list (tree_classdef_superclass *sc) { append (sc); } tree_classdef_superclass_list (const base_list<tree_classdef_superclass *>& a) : base_list<tree_classdef_superclass *> (a) { } OCTAVE_DISABLE_COPY_MOVE (tree_classdef_superclass_list) ~tree_classdef_superclass_list (); void accept (tree_walker& tw) { tw.visit_classdef_superclass_list (*this); } }; template <typename T> class tree_classdef_element : public tree { public: tree_classdef_element (tree_classdef_attribute_list *a, T *elt_list, comment_list *lc, comment_list *tc, int l = -1, int c = -1) : tree (l, c), m_attr_list (a), m_elt_list (elt_list), m_lead_comm (lc), m_trail_comm (tc) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_element) ~tree_classdef_element () { delete m_attr_list; delete m_elt_list; delete m_lead_comm; delete m_trail_comm; } tree_classdef_attribute_list * attribute_list () { return m_attr_list; } T * element_list () { return m_elt_list; } comment_list * leading_comment () { return m_lead_comm; } comment_list * trailing_comment () { return m_trail_comm; } void accept (tree_walker&) { } private: // List of attributes that apply to this class. tree_classdef_attribute_list *m_attr_list; // The list of objects contained in this block. T *m_elt_list; // Comments preceding the token marking the beginning of the block. comment_list *m_lead_comm; // Comments preceding the END token marking the end of the block. comment_list *m_trail_comm; }; class tree_classdef_property { public: tree_classdef_property (tree_arg_validation *av, comment_list *comments = nullptr); OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_property) ~tree_classdef_property (); tree_identifier * ident (); tree_expression * expression (); comment_list * comments () const { return m_comments; } void doc_string (const std::string& txt) { m_doc_string = txt; } std::string doc_string () const { return m_doc_string; } bool have_doc_string () const { return ! m_doc_string.empty (); } void accept (tree_walker& tw) { tw.visit_classdef_property (*this); } private: tree_arg_validation *m_av; comment_list *m_comments; std::string m_doc_string; }; class tree_classdef_property_list : public base_list<tree_classdef_property *> { public: tree_classdef_property_list () { } tree_classdef_property_list (tree_classdef_property *p) { append (p); } tree_classdef_property_list (const base_list<tree_classdef_property *>& a) : base_list<tree_classdef_property *> (a) { } OCTAVE_DISABLE_COPY_MOVE (tree_classdef_property_list) ~tree_classdef_property_list (); void accept (tree_walker& tw) { tw.visit_classdef_property_list (*this); } }; class tree_classdef_properties_block : public tree_classdef_element<tree_classdef_property_list> { public: tree_classdef_properties_block (tree_classdef_attribute_list *a, tree_classdef_property_list *plist, comment_list *lc, comment_list *tc, int l = -1, int c = -1) : tree_classdef_element<tree_classdef_property_list> (a, plist, lc, tc, l, c) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_properties_block) ~tree_classdef_properties_block () = default; void accept (tree_walker& tw) { tw.visit_classdef_properties_block (*this); } }; class tree_classdef_methods_list : public base_list<octave_value> { public: tree_classdef_methods_list () { } tree_classdef_methods_list (const octave_value& f) { append (f); } tree_classdef_methods_list (const base_list<octave_value>& a) : base_list<octave_value> (a) { } OCTAVE_DISABLE_COPY_MOVE (tree_classdef_methods_list) ~tree_classdef_methods_list () = default; void accept (tree_walker& tw) { tw.visit_classdef_methods_list (*this); } }; class tree_classdef_methods_block : public tree_classdef_element<tree_classdef_methods_list> { public: tree_classdef_methods_block (tree_classdef_attribute_list *a, tree_classdef_methods_list *mlist, comment_list *lc, comment_list *tc, int l = -1, int c = -1) : tree_classdef_element<tree_classdef_methods_list> (a, mlist, lc, tc, l, c) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_methods_block) ~tree_classdef_methods_block () = default; void accept (tree_walker& tw) { tw.visit_classdef_methods_block (*this); } }; class tree_classdef_event { public: tree_classdef_event (tree_identifier *i = nullptr, comment_list *comments = nullptr); OCTAVE_DISABLE_COPY_MOVE (tree_classdef_event) ~tree_classdef_event () { delete m_id; delete m_comments; } tree_identifier * ident () { return m_id; } comment_list * comments () const { return m_comments; } void doc_string (const std::string& txt) { m_doc_string = txt; } std::string doc_string () const { return m_doc_string; } bool have_doc_string () const { return ! m_doc_string.empty (); } void accept (tree_walker& tw) { tw.visit_classdef_event (*this); } private: tree_identifier *m_id; comment_list *m_comments; std::string m_doc_string; }; class tree_classdef_events_list : public base_list<tree_classdef_event *> { public: tree_classdef_events_list () { } tree_classdef_events_list (tree_classdef_event *e) { append (e); } tree_classdef_events_list (const base_list<tree_classdef_event *>& a) : base_list<tree_classdef_event *> (a) { } OCTAVE_DISABLE_COPY_MOVE (tree_classdef_events_list) ~tree_classdef_events_list (); void accept (tree_walker& tw) { tw.visit_classdef_events_list (*this); } }; class tree_classdef_events_block : public tree_classdef_element<tree_classdef_events_list> { public: tree_classdef_events_block (tree_classdef_attribute_list *a, tree_classdef_events_list *elist, comment_list *lc, comment_list *tc, int l = -1, int c = -1) : tree_classdef_element<tree_classdef_events_list> (a, elist, lc, tc, l, c) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_events_block) ~tree_classdef_events_block () = default; void accept (tree_walker& tw) { tw.visit_classdef_events_block (*this); } }; class tree_classdef_enum { public: tree_classdef_enum (tree_identifier *i, tree_expression *e, comment_list *comments); OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_enum) ~tree_classdef_enum () { delete m_id; delete m_expr; delete m_comments; } tree_identifier * ident () { return m_id; } tree_expression * expression () { return m_expr; } comment_list * comments () const { return m_comments; } void doc_string (const std::string& txt) { m_doc_string = txt; } std::string doc_string () const { return m_doc_string; } bool have_doc_string () const { return ! m_doc_string.empty (); } void accept (tree_walker& tw) { tw.visit_classdef_enum (*this); } private: tree_identifier *m_id; tree_expression *m_expr; comment_list *m_comments; std::string m_doc_string; }; class tree_classdef_enum_list : public base_list<tree_classdef_enum *> { public: tree_classdef_enum_list () { } tree_classdef_enum_list (tree_classdef_enum *e) { append (e); } tree_classdef_enum_list (const base_list<tree_classdef_enum *>& a) : base_list<tree_classdef_enum *> (a) { } OCTAVE_DISABLE_COPY_MOVE (tree_classdef_enum_list) ~tree_classdef_enum_list (); void accept (tree_walker& tw) { tw.visit_classdef_enum_list (*this); } }; class tree_classdef_enum_block : public tree_classdef_element<tree_classdef_enum_list> { public: tree_classdef_enum_block (tree_classdef_attribute_list *a, tree_classdef_enum_list *elist, comment_list *lc, comment_list *tc, int l = -1, int c = -1) : tree_classdef_element<tree_classdef_enum_list> (a, elist, lc, tc, l, c) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_enum_block) ~tree_classdef_enum_block () = default; void accept (tree_walker& tw) { tw.visit_classdef_enum_block (*this); } }; class tree_classdef_body { public: typedef std::list<tree_classdef_properties_block *>::iterator properties_list_iterator; typedef std::list<tree_classdef_properties_block *>::const_iterator properties_list_const_iterator; typedef std::list<tree_classdef_methods_block *>::iterator methods_list_iterator; typedef std::list<tree_classdef_methods_block *>::const_iterator methods_list_const_iterator; typedef std::list<tree_classdef_events_block *>::iterator events_list_iterator; typedef std::list<tree_classdef_events_block *>::const_iterator events_list_const_iterator; typedef std::list<tree_classdef_enum_block *>::iterator enum_list_iterator; typedef std::list<tree_classdef_enum_block *>::const_iterator enum_list_const_iterator; tree_classdef_body (); tree_classdef_body (tree_classdef_properties_block *pb); tree_classdef_body (tree_classdef_methods_block *mb); tree_classdef_body (tree_classdef_events_block *evb); tree_classdef_body (tree_classdef_enum_block *enb); OCTAVE_DISABLE_COPY_MOVE (tree_classdef_body) ~tree_classdef_body (); void append (tree_classdef_properties_block *pb) { m_properties_lst.push_back (pb); } void append (tree_classdef_methods_block *mb) { m_methods_lst.push_back (mb); } void append (tree_classdef_events_block *evb) { m_events_lst.push_back (evb); } void append (tree_classdef_enum_block *enb) { m_enum_lst.push_back (enb); } std::list<tree_classdef_properties_block *> properties_list () { return m_properties_lst; } std::list<tree_classdef_methods_block *> methods_list () { return m_methods_lst; } std::list<tree_classdef_events_block *> events_list () { return m_events_lst; } std::list<tree_classdef_enum_block *> enum_list () { return m_enum_lst; } void doc_string (const std::string& txt) { m_doc_string = txt; } std::string doc_string () const { return m_doc_string; } bool have_doc_string () const { return ! m_doc_string.empty (); } void accept (tree_walker& tw) { tw.visit_classdef_body (*this); } private: std::string get_doc_string (comment_list *comment) const; std::list<tree_classdef_properties_block *> m_properties_lst; std::list<tree_classdef_methods_block *> m_methods_lst; std::list<tree_classdef_events_block *> m_events_lst; std::list<tree_classdef_enum_block *> m_enum_lst; std::string m_doc_string; }; // Classdef definition. class tree_classdef : public tree_command { public: 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_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) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef) ~tree_classdef () { delete m_attr_list; delete m_id; delete m_supclass_list; delete m_element_list; delete m_lead_comm; delete m_trail_comm; } symbol_scope scope () { return m_scope; } tree_classdef_attribute_list * attribute_list () { return m_attr_list; } tree_identifier * ident () { return m_id; } tree_classdef_superclass_list * superclass_list () { return m_supclass_list; } tree_classdef_body * body () { return m_element_list; } comment_list * leading_comment () { return m_lead_comm; } comment_list * trailing_comment () { return m_trail_comm; } std::string package_name () const { return m_pack_name; } std::string file_name () const { return m_file_name; } octave_value make_meta_class (interpreter& interp, bool is_at_folder = false); std::string doc_string () const { return m_help_text; } void accept (tree_walker& tw) { tw.visit_classdef (*this); } private: // The scope that was used when parsing the classdef object and that // corresponds to any identifiers that were found in attribute lists // (for example). Used again when computing the meta class object. symbol_scope m_scope; std::string m_help_text; tree_classdef_attribute_list *m_attr_list; tree_identifier *m_id; tree_classdef_superclass_list *m_supclass_list; tree_classdef_body *m_element_list; comment_list *m_lead_comm; comment_list *m_trail_comm; std::string m_pack_name; std::string m_file_name; }; OCTAVE_END_NAMESPACE(octave) #endif