1 //===-- REPL.h --------------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef lldb_REPL_h
11 #define lldb_REPL_h
12 
13 #include <string>
14 
15 #include "lldb/../../source/Commands/CommandObjectExpression.h"
16 #include "lldb/Interpreter/OptionGroupFormat.h"
17 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
18 
19 namespace lldb_private {
20 
21 class REPL : public IOHandlerDelegate {
22 public:
23   //----------------------------------------------------------------------
24   // See TypeSystem.h for how to add subclasses to this.
25   //----------------------------------------------------------------------
26   enum LLVMCastKind { eKindClang, eKindSwift, eKindGo, kNumKinds };
27 
getKind()28   LLVMCastKind getKind() const { return m_kind; }
29 
30   REPL(LLVMCastKind kind, Target &target);
31 
32   ~REPL() override;
33 
34   //------------------------------------------------------------------
35   /// Get a REPL with an existing target (or, failing that, a debugger to use),
36   /// and (optional) extra arguments for the compiler.
37   ///
38   /// @param[out] error
39   ///     If this language is supported but the REPL couldn't be created, this
40   ///     error is populated with the reason.
41   ///
42   /// @param[in] language
43   ///     The language to create a REPL for.
44   ///
45   /// @param[in] debugger
46   ///     If provided, and target is nullptr, the debugger to use when setting
47   ///     up a top-level REPL.
48   ///
49   /// @param[in] target
50   ///     If provided, the target to put the REPL inside.
51   ///
52   /// @param[in] repl_options
53   ///     If provided, additional options for the compiler when parsing REPL
54   ///     expressions.
55   ///
56   /// @return
57   ///     The range of the containing object in the target process.
58   //------------------------------------------------------------------
59   static lldb::REPLSP Create(Status &Status, lldb::LanguageType language,
60                              Debugger *debugger, Target *target,
61                              const char *repl_options);
62 
SetFormatOptions(const OptionGroupFormat & options)63   void SetFormatOptions(const OptionGroupFormat &options) {
64     m_format_options = options;
65   }
66 
67   void
SetValueObjectDisplayOptions(const OptionGroupValueObjectDisplay & options)68   SetValueObjectDisplayOptions(const OptionGroupValueObjectDisplay &options) {
69     m_varobj_options = options;
70   }
71 
72   void
SetCommandOptions(const CommandObjectExpression::CommandOptions & options)73   SetCommandOptions(const CommandObjectExpression::CommandOptions &options) {
74     m_command_options = options;
75   }
76 
SetCompilerOptions(const char * options)77   void SetCompilerOptions(const char *options) {
78     if (options)
79       m_compiler_options = options;
80   }
81 
82   lldb::IOHandlerSP GetIOHandler();
83 
84   Status RunLoop();
85 
86   //------------------------------------------------------------------
87   // IOHandler::Delegate functions
88   //------------------------------------------------------------------
89   void IOHandlerActivated(IOHandler &io_handler) override;
90 
91   bool IOHandlerInterrupt(IOHandler &io_handler) override;
92 
93   void IOHandlerInputInterrupted(IOHandler &io_handler,
94                                  std::string &line) override;
95 
96   const char *IOHandlerGetFixIndentationCharacters() override;
97 
98   ConstString IOHandlerGetControlSequence(char ch) override;
99 
100   const char *IOHandlerGetCommandPrefix() override;
101 
102   const char *IOHandlerGetHelpPrologue() override;
103 
104   bool IOHandlerIsInputComplete(IOHandler &io_handler,
105                                 StringList &lines) override;
106 
107   int IOHandlerFixIndentation(IOHandler &io_handler, const StringList &lines,
108                               int cursor_position) override;
109 
110   void IOHandlerInputComplete(IOHandler &io_handler,
111                               std::string &line) override;
112 
113   int IOHandlerComplete(IOHandler &io_handler, const char *current_line,
114                         const char *cursor, const char *last_char,
115                         int skip_first_n_matches, int max_matches,
116                         StringList &matches, StringList &descriptions) override;
117 
118 protected:
119   static int CalculateActualIndentation(const StringList &lines);
120 
121   //----------------------------------------------------------------------
122   // Subclasses should override these functions to implement a functional REPL.
123   //----------------------------------------------------------------------
124 
125   virtual Status DoInitialization() = 0;
126 
127   virtual ConstString GetSourceFileBasename() = 0;
128 
129   virtual const char *GetAutoIndentCharacters() = 0;
130 
131   virtual bool SourceIsComplete(const std::string &source) = 0;
132 
133   virtual lldb::offset_t GetDesiredIndentation(
134       const StringList &lines, int cursor_position,
135       int tab_size) = 0; // LLDB_INVALID_OFFSET means no change
136 
137   virtual lldb::LanguageType GetLanguage() = 0;
138 
139   virtual bool PrintOneVariable(Debugger &debugger,
140                                 lldb::StreamFileSP &output_sp,
141                                 lldb::ValueObjectSP &valobj_sp,
142                                 ExpressionVariable *var = nullptr) = 0;
143 
144   virtual int CompleteCode(const std::string &current_code,
145                            StringList &matches) = 0;
146 
147   OptionGroupFormat m_format_options = OptionGroupFormat(lldb::eFormatDefault);
148   OptionGroupValueObjectDisplay m_varobj_options;
149   CommandObjectExpression::CommandOptions m_command_options;
150   std::string m_compiler_options;
151 
152   bool m_enable_auto_indent = true;
153   std::string m_indent_str; // Use this string for each level of indentation
154   std::string m_current_indent_str;
155   uint32_t m_current_indent_level = 0;
156 
157   std::string m_repl_source_path;
158   bool m_dedicated_repl_mode = false;
159 
160   StringList m_code; // All accumulated REPL statements are saved here
161 
162   Target &m_target;
163   lldb::IOHandlerSP m_io_handler_sp;
164   LLVMCastKind m_kind;
165 
166 private:
167   std::string GetSourcePath();
168 };
169 
170 } // namespace lldb_private
171 
172 #endif // lldb_REPL_h
173