diff --git a/doc/server.org b/doc/server.org index 8ab5d8ee1e..a9dacfad86 100644 --- a/doc/server.org +++ b/doc/server.org @@ -70,11 +70,13 @@ buffer, then the command is ignored. ** Extracting information #+BEGIN_SRC -INFO [line-number] +INFO [line-number] [column-number]? #+END_SRC This command extracts typing information associated with line -=[line-number]= (in the current file). +=[line-number]= (in the current file) and =[column-number]=. +If =[column-number]= is not provided then (potentially) long +information is not included. Lean produces a possible empty sequence of entries delimited by the lines =-- BEGININFO= and =-- ENDINFO=. @@ -147,6 +149,17 @@ Information about introduced coercions is of the form -- ACK #+END_SRC +When =[column-number]= is provided in the =INFO= command, the type of terms surrounded by =()= +is also included. The ouput has the form + +#+BEGIN_SRC +-- EXTRA_TYPE|[line-number]|[column-number] +[term] +-- +[type] +-- ACK +#+END_SRC + Here is an example of output produced by Lean #+BEGIN_SRC diff --git a/src/frontends/lean/info_manager.cpp b/src/frontends/lean/info_manager.cpp index 81ef566804..bb484be9e6 100644 --- a/src/frontends/lean/info_manager.cpp +++ b/src/frontends/lean/info_manager.cpp @@ -30,6 +30,11 @@ public: info_data_cell():m_column(0), m_rc(0) {} info_data_cell(unsigned c):m_column(c), m_rc(0) {} virtual ~info_data_cell() {} + /** \brief Return true iff the information is considered "cheap" + If the column number is not provided in the method info_manager::display, + then only "cheap" information is displayed. + */ + virtual bool is_cheap() const { return true; } virtual info_kind kind() const = 0; unsigned get_column() const { return m_column; } virtual void display(io_state_stream const & ios, unsigned line) const = 0; @@ -58,6 +63,7 @@ public: int compare(info_data_cell const & d) const { return m_ptr->compare(d); } info_data instantiate(substitution & s) const; unsigned get_column() const { return m_ptr->get_column(); } + bool is_cheap() const { return m_ptr->is_cheap(); } void display(io_state_stream const & ios, unsigned line) const { m_ptr->display(ios, line); } info_data_cell const * raw() const { return m_ptr; } }; @@ -111,6 +117,7 @@ public: extra_type_info_data(unsigned c, expr const & e, expr const & t):info_data_cell(c), m_expr(e), m_type(t) {} virtual info_kind kind() const { return info_kind::ExtraType; } + virtual bool is_cheap() const { return false; } virtual void display(io_state_stream const & ios, unsigned line) const { ios << "-- EXTRA_TYPE|" << line << "|" << get_column() << "\n"; @@ -472,25 +479,27 @@ struct info_manager::imp { return !m_line_valid[l]; } - void display_core(environment const & env, options const & o, io_state const & ios, unsigned line) { + void display_core(environment const & env, options const & o, io_state const & ios, unsigned line, + optional const & col) { io_state_stream out = regular(env, ios).update_options(o); m_line_data[line].for_each([&](info_data const & d) { - d.display(out, line); + if ((!col && d.is_cheap()) || (col && d.get_column() == *col)) + d.display(out, line); }); } - void display(environment const & env, io_state const & ios, unsigned line) { + void display(environment const & env, io_state const & ios, unsigned line, optional const & col) { lock_guard lc(m_mutex); if (line >= m_line_data.size() || m_line_data[line].empty()) { // do nothing } else if (m_env_info.empty()) { - display_core(env, ios.get_options(), ios, line); + display_core(env, ios.get_options(), ios, line, col); } else { auto it = m_env_info.begin(); auto end = m_env_info.end(); lean_assert(it != end); if (it->m_line > line) { - display_core(env, ios.get_options(), ios, line); + display_core(env, ios.get_options(), ios, line, col); return; } while (true) { @@ -499,7 +508,7 @@ struct info_manager::imp { auto next = it; ++next; if (next == end || next->m_line > line) { - display_core(it->m_env, join(it->m_options, ios.get_options()), ios, line); + display_core(it->m_env, join(it->m_options, ios.get_options()), ios, line, col); return; } it = next; @@ -596,7 +605,9 @@ void info_manager::save_environment_options(unsigned l, environment const & env, void info_manager::clear() { m_ptr->clear(); } optional> info_manager::get_final_env_opts() const { return m_ptr->get_final_env_opts(); } optional> info_manager::get_closest_env_opts(unsigned linenum) const { return m_ptr->get_closest_env_opts(linenum); } -void info_manager::display(environment const & env, io_state const & ios, unsigned line) const { m_ptr->display(env, ios, line); } +void info_manager::display(environment const & env, io_state const & ios, unsigned line, optional const & col) const { + m_ptr->display(env, ios, line, col); +} unsigned info_manager::get_processed_upto() const { return m_ptr->m_processed_upto; } optional info_manager::get_type_at(unsigned line, unsigned col) const { return m_ptr->get_type_at(line, col); } optional info_manager::get_meta_at(unsigned line, unsigned col) const { return m_ptr->get_meta_at(line, col); } diff --git a/src/frontends/lean/info_manager.h b/src/frontends/lean/info_manager.h index 2812d0a370..ef7dc49966 100644 --- a/src/frontends/lean/info_manager.h +++ b/src/frontends/lean/info_manager.h @@ -43,7 +43,8 @@ public: optional get_type_at(unsigned line, unsigned col) const; optional get_meta_at(unsigned line, unsigned col) const; void clear(); - void display(environment const & env, io_state const & ios, unsigned line) const; + void display(environment const & env, io_state const & ios, unsigned line, + optional const & col = optional()) const; void block_new_info(bool f); unsigned get_processed_upto() const; }; diff --git a/src/frontends/lean/server.cpp b/src/frontends/lean/server.cpp index 015d215e1e..52711bfcc5 100644 --- a/src/frontends/lean/server.cpp +++ b/src/frontends/lean/server.cpp @@ -353,15 +353,25 @@ unsigned server::get_line_num(std::string const & line, std::string const & cmd) return r; } -pair server::get_line_col_num(std::string const & line, std::string const & cmd) { +pair> server::get_line_opt_col_num(std::string const & line, std::string const & cmd) { std::string data = line.substr(cmd.size()); unsigned i = 0; consume_spaces(data, i); unsigned line_num = consume_num(data, i); check_line_num(line_num); consume_spaces(data, i); + if (i == data.size()) + return mk_pair(line_num, optional()); unsigned colnum = consume_num(data, i); - return mk_pair(line_num, colnum); + return mk_pair(line_num, optional(colnum)); +} + +pair server::get_line_col_num(std::string const & line, std::string const & cmd) { + auto r = get_line_opt_col_num(line, cmd); + if (r.second) + return mk_pair(r.first, *r.second); + else + return mk_pair(r.first, 0); } void server::check_file() { @@ -405,7 +415,7 @@ void server::set_option(std::string const & line) { m_out << "-- ENDSET" << std::endl; } -void server::show_info(unsigned line_num) { +void server::show_info(unsigned line_num, optional const & col_num) { check_file(); m_out << "-- BEGININFO"; if (m_file->infom().is_invalidated(line_num)) @@ -413,7 +423,7 @@ void server::show_info(unsigned line_num) { if (line_num >= m_file->infom().get_processed_upto()) m_out << " NAY"; m_out << std::endl; - m_file->infom().display(m_env, m_ios, line_num); + m_file->infom().display(m_env, m_ios, line_num, col_num); m_out << "-- ENDINFO" << std::endl; } @@ -668,8 +678,8 @@ bool server::operator()(std::istream & in) { unsigned line_num = get_line_num(line, g_remove); remove_line(line_num-1); } else if (is_command(g_info, line)) { - unsigned line_num = get_line_num(line, g_info); - show_info(line_num); + auto line_col = get_line_opt_col_num(line, g_info); + show_info(line_col.first, line_col.second); } else if (is_command(g_set, line)) { read_line(in, line); set_option(line); diff --git a/src/frontends/lean/server.h b/src/frontends/lean/server.h index e2fce38fc3..c9706f9793 100644 --- a/src/frontends/lean/server.h +++ b/src/frontends/lean/server.h @@ -44,7 +44,6 @@ class server { class worker { snapshot m_empty_snapshot; definition_cache & m_cache; - atomic_bool m_busy; file_ptr m_todo_file; unsigned m_todo_line_num; options m_todo_options; @@ -77,7 +76,7 @@ class server { void replace_line(unsigned line_num, std::string const & new_line); void insert_line(unsigned line_num, std::string const & new_line); void remove_line(unsigned line_num); - void show_info(unsigned line_num); + void show_info(unsigned line_num, optional const & col_num); void process_from(unsigned line_num); void set_option(std::string const & line); void eval_core(environment const & env, options const & o, std::string const & line); @@ -90,6 +89,7 @@ class server { void show_options(); void show(bool valid); unsigned get_line_num(std::string const & line, std::string const & cmd); + pair> get_line_opt_col_num(std::string const & line, std::string const & cmd); pair get_line_col_num(std::string const & line, std::string const & cmd); void find_goal_matches(unsigned line_num, unsigned col_num, std::string const & filters); diff --git a/tests/lean/interactive/t4.input.expected.out b/tests/lean/interactive/t4.input.expected.out index dfd7133731..3538a731ba 100644 --- a/tests/lean/interactive/t4.input.expected.out +++ b/tests/lean/interactive/t4.input.expected.out @@ -5,11 +5,6 @@ -- IDENTIFIER|6|6 epsilon -- ACK --- EXTRA_TYPE|6|14 -λ (x : nat), true --- -nat → Prop --- ACK -- SYMBOL|6|14 ( -- ACK