1 //===-- REPL.h --------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_EXPRESSION_REPL_H
10 #define LLDB_EXPRESSION_REPL_H
11 
12 #include <string>
13 
14 #include "lldb/Core/IOHandler.h"
15 #include "lldb/Interpreter/OptionGroupFormat.h"
16 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
17 #include "lldb/Target/Target.h"
18 #include "llvm/Support/ExtensibleRTTI.h"
19 
20 namespace lldb_private {
21 
22 class REPL : public IOHandlerDelegate,
23              public llvm::RTTIExtends<REPL, llvm::RTTIRoot> {
24 public:
25   /// LLVM RTTI support
26   static char ID;
27 
28   REPL(Target &target);
29 
30   ~REPL() override;
31 
32   /// Get a REPL with an existing target (or, failing that, a debugger to use),
33   /// and (optional) extra arguments for the compiler.
34   ///
35   /// \param[out] Status
36   ///     If this language is supported but the REPL couldn't be created, this
37   ///     error is populated with the reason.
38   ///
39   /// \param[in] language
40   ///     The language to create a REPL for.
41   ///
42   /// \param[in] debugger
43   ///     If provided, and target is nullptr, the debugger to use when setting
44   ///     up a top-level REPL.
45   ///
46   /// \param[in] target
47   ///     If provided, the target to put the REPL inside.
48   ///
49   /// \param[in] repl_options
50   ///     If provided, additional options for the compiler when parsing REPL
51   ///     expressions.
52   ///
53   /// \return
54   ///     The range of the containing object in the target process.
55   static lldb::REPLSP Create(Status &Status, lldb::LanguageType language,
56                              Debugger *debugger, Target *target,
57                              const char *repl_options);
58 
SetFormatOptions(const OptionGroupFormat & options)59   void SetFormatOptions(const OptionGroupFormat &options) {
60     m_format_options = options;
61   }
62 
63   void
SetValueObjectDisplayOptions(const OptionGroupValueObjectDisplay & options)64   SetValueObjectDisplayOptions(const OptionGroupValueObjectDisplay &options) {
65     m_varobj_options = options;
66   }
67 
SetEvaluateOptions(const EvaluateExpressionOptions & options)68   void SetEvaluateOptions(const EvaluateExpressionOptions &options) {
69     m_expr_options = options;
70   }
71 
SetCompilerOptions(const char * options)72   void SetCompilerOptions(const char *options) {
73     if (options)
74       m_compiler_options = options;
75   }
76 
77   lldb::IOHandlerSP GetIOHandler();
78 
79   Status RunLoop();
80 
81   // IOHandler::Delegate functions
82   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;
83 
84   bool IOHandlerInterrupt(IOHandler &io_handler) override;
85 
86   void IOHandlerInputInterrupted(IOHandler &io_handler,
87                                  std::string &line) override;
88 
89   const char *IOHandlerGetFixIndentationCharacters() override;
90 
91   llvm::StringRef IOHandlerGetControlSequence(char ch) override;
92 
93   const char *IOHandlerGetCommandPrefix() override;
94 
95   const char *IOHandlerGetHelpPrologue() override;
96 
97   bool IOHandlerIsInputComplete(IOHandler &io_handler,
98                                 StringList &lines) override;
99 
100   int IOHandlerFixIndentation(IOHandler &io_handler, const StringList &lines,
101                               int cursor_position) override;
102 
103   void IOHandlerInputComplete(IOHandler &io_handler,
104                               std::string &line) override;
105 
106   void IOHandlerComplete(IOHandler &io_handler,
107                          CompletionRequest &request) override;
108 
109 protected:
110   /// Method that can be optionally overriden by subclasses to get notified
111   /// whenever an expression has been evaluated. The params of this method
112   /// include the inputs and outputs of the expression evaluation.
113   ///
114   /// Note: meta commands that start with : are not covered by this method.
115   ///
116   /// \return
117   ///   An \a Error object that, if it is a failure, aborts the regular
118   ///   REPL expression result handling.
119   virtual llvm::Error
OnExpressionEvaluated(const ExecutionContext & exe_ctx,llvm::StringRef code,const EvaluateExpressionOptions & expr_options,lldb::ExpressionResults execution_results,const lldb::ValueObjectSP & result_valobj_sp,const Status & error)120   OnExpressionEvaluated(const ExecutionContext &exe_ctx, llvm::StringRef code,
121                         const EvaluateExpressionOptions &expr_options,
122                         lldb::ExpressionResults execution_results,
123                         const lldb::ValueObjectSP &result_valobj_sp,
124                         const Status &error) {
125     return llvm::Error::success();
126   }
127 
128   static int CalculateActualIndentation(const StringList &lines);
129 
130   // Subclasses should override these functions to implement a functional REPL.
131 
132   virtual Status DoInitialization() = 0;
133 
134   virtual llvm::StringRef GetSourceFileBasename() = 0;
135 
136   virtual const char *GetAutoIndentCharacters() = 0;
137 
138   virtual bool SourceIsComplete(const std::string &source) = 0;
139 
140   virtual lldb::offset_t GetDesiredIndentation(
141       const StringList &lines, int cursor_position,
142       int tab_size) = 0; // LLDB_INVALID_OFFSET means no change
143 
144   virtual lldb::LanguageType GetLanguage() = 0;
145 
146   virtual bool PrintOneVariable(Debugger &debugger,
147                                 lldb::StreamFileSP &output_sp,
148                                 lldb::ValueObjectSP &valobj_sp,
149                                 ExpressionVariable *var = nullptr) = 0;
150 
151   virtual void CompleteCode(const std::string &current_code,
152                             CompletionRequest &request) = 0;
153 
154   OptionGroupFormat m_format_options = OptionGroupFormat(lldb::eFormatDefault);
155   OptionGroupValueObjectDisplay m_varobj_options;
156   EvaluateExpressionOptions m_expr_options;
157   std::string m_compiler_options;
158 
159   bool m_enable_auto_indent = true;
160   std::string m_indent_str; // Use this string for each level of indentation
161   std::string m_current_indent_str;
162   uint32_t m_current_indent_level = 0;
163 
164   std::string m_repl_source_path;
165   bool m_dedicated_repl_mode = false;
166 
167   StringList m_code; // All accumulated REPL statements are saved here
168 
169   Target &m_target;
170   lldb::IOHandlerSP m_io_handler_sp;
171 
172 private:
173   std::string GetSourcePath();
174 };
175 
176 } // namespace lldb_private
177 
178 #endif // LLDB_EXPRESSION_REPL_H
179