1 #pragma once
2 #include "dispatcher.hpp"
3 #include "project_build.hpp"
4 #include "tooltips.hpp"
5 #include <atomic>
6 #include <boost/filesystem.hpp>
7 #include <gtkmm.h>
8 #include <iostream>
9 #include <unordered_map>
10 
11 namespace Project {
12   /// Returns folder of current view if any. Otherwise returns directory folder if any, or if not, working directory.
13   boost::filesystem::path get_preferably_view_folder();
14   /// Returns directory folder if any. Otherwise returns folder of current view if any, or if not, working directory.
15   boost::filesystem::path get_preferably_directory_folder();
16   void save_files(const boost::filesystem::path &path);
17   void on_save(size_t index);
18 
19   class DebugRunArguments {
20   public:
21     std::string arguments;
22     bool remote_enabled;
23     std::string remote_host_port;
24   };
25 
26   class DebugOptions : public Gtk::Popover {
27   public:
DebugOptions()28     DebugOptions() : Gtk::Popover(), vbox(Gtk::Orientation::ORIENTATION_VERTICAL) { add(vbox); }
29     Gtk::Box vbox;
30   };
31 
32   extern boost::filesystem::path debug_last_stop_file_path;
33   extern std::unordered_map<std::string, std::string> run_arguments;
34   extern std::unordered_map<std::string, DebugRunArguments> debug_run_arguments;
35   extern std::atomic<bool> compiling;
36   extern std::atomic<bool> debugging;
37   extern std::pair<boost::filesystem::path, std::pair<int, int>> debug_stop;
38   extern std::string debug_status;
39   Gtk::Label &debug_status_label();
40   void debug_update_status(const std::string &new_debug_status);
41   void debug_activate_menu_items();
42   void debug_update_stop();
43 
44   class Base : public std::enable_shared_from_this<Base> {
45   protected:
46     static std::unique_ptr<DebugOptions> debug_options;
47 
48   public:
49     Base() = default;
Base(std::unique_ptr<Build> && build)50     Base(std::unique_ptr<Build> &&build) : build(std::move(build)) {}
51     virtual ~Base() = default;
52 
53     std::unique_ptr<Build> build;
54 
55     Dispatcher dispatcher;
56 
57     virtual std::pair<std::string, std::string> get_run_arguments();
58     virtual void compile();
59     virtual void compile_and_run();
60     virtual void recreate_build();
61 
62     void show_symbols();
63 
64     virtual std::pair<std::string, std::string> debug_get_run_arguments();
debug_get_options()65     virtual Project::DebugOptions *debug_get_options() { return nullptr; }
66     Tooltips debug_variable_tooltips;
67     virtual void debug_compile_and_start();
68     virtual void debug_start(const std::string &command, const boost::filesystem::path &path, const std::string &remote_host);
debug_continue()69     virtual void debug_continue() {}
debug_stop()70     virtual void debug_stop() {}
debug_kill()71     virtual void debug_kill() {}
debug_step_over()72     virtual void debug_step_over() {}
debug_step_into()73     virtual void debug_step_into() {}
debug_step_out()74     virtual void debug_step_out() {}
debug_backtrace()75     virtual void debug_backtrace() {}
debug_show_variables()76     virtual void debug_show_variables() {}
debug_run_command(const std::string & command)77     virtual void debug_run_command(const std::string &command) {}
debug_add_breakpoint(const boost::filesystem::path & file_path,int line_nr)78     virtual void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {}
debug_remove_breakpoint(const boost::filesystem::path & file_path,int line_nr,int line_count)79     virtual void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {}
debug_is_running()80     virtual bool debug_is_running() { return false; }
debug_write(const std::string & buffer)81     virtual void debug_write(const std::string &buffer) {}
82   };
83 
84   class LLDB : public virtual Base {
85   public:
86 #ifdef JUCI_ENABLE_DEBUG
87     std::pair<std::string, std::string> debug_get_run_arguments() override;
88     Project::DebugOptions *debug_get_options() override;
89     void debug_compile_and_start() override;
90     void debug_start(const std::string &command, const boost::filesystem::path &path, const std::string &remote_host) override;
91     void debug_continue() override;
92     void debug_stop() override;
93     void debug_kill() override;
94     void debug_step_over() override;
95     void debug_step_into() override;
96     void debug_step_out() override;
97     void debug_backtrace() override;
98     void debug_show_variables() override;
99     void debug_run_command(const std::string &command) override;
100     void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) override;
101     void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) override;
102     bool debug_is_running() override;
103     void debug_write(const std::string &buffer) override;
104 #endif
105   };
106 
107   class LanguageProtocol : public virtual Base {
108   public:
109     virtual std::string get_language_id() = 0;
110   };
111 
112   class Clang : public LLDB {
113   public:
Clang(std::unique_ptr<Build> && build)114     Clang(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
115 
116     std::pair<std::string, std::string> get_run_arguments() override;
117     void compile() override;
118     void compile_and_run() override;
119     void recreate_build() override;
120   };
121 
122   class Markdown : public Base {
123   public:
Markdown(std::unique_ptr<Build> && build)124     Markdown(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
125 
126     void compile_and_run() override;
127   };
128 
129   class Python : public LanguageProtocol {
130   public:
Python(std::unique_ptr<Build> && build)131     Python(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
132 
133     void compile_and_run() override;
134 
get_language_id()135     std::string get_language_id() override { return "python"; }
136   };
137 
138   class JavaScript : public LanguageProtocol {
139   public:
JavaScript(std::unique_ptr<Build> && build)140     JavaScript(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
141 
142     void compile_and_run() override;
143 
get_language_id()144     std::string get_language_id() override { return "javascript"; }
145   };
146 
147   class HTML : public Base {
148   public:
HTML(std::unique_ptr<Build> && build)149     HTML(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
150 
151     void compile_and_run() override;
152   };
153 
154   class Rust : public LLDB, public LanguageProtocol {
155   public:
Rust(std::unique_ptr<Build> && build)156     Rust(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
157 
158     std::pair<std::string, std::string> get_run_arguments() override;
159     void compile() override;
160     void compile_and_run() override;
161 
get_language_id()162     std::string get_language_id() override { return "rust"; }
163   };
164 
165   class Go : public LanguageProtocol {
166   public:
Go(std::unique_ptr<Build> && build)167     Go(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
168 
169     void compile_and_run() override;
170 
get_language_id()171     std::string get_language_id() override { return "go"; }
172   };
173 
174   class Julia : public LanguageProtocol {
175   public:
Julia(std::unique_ptr<Build> && build)176     Julia(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
177 
178     void compile_and_run() override;
179 
get_language_id()180     std::string get_language_id() override { return "julia"; }
181   };
182 
183   std::shared_ptr<Base> create();
184   extern std::shared_ptr<Base> current;
185 }; // namespace Project
186