From db642080b5dcd007f80cf8ed15e48f567a5f537d Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 2 Sep 2016 12:00:27 -0400
Subject: [PATCH 14/44] FIXME: start rewrite of fix-it printing (to use
 edit_context); contains the apply_changes change

---
 gcc/diagnostic-show-locus.c |  35 +++++++++++
 gcc/edit-context.c          | 146 +++++++++-----------------------------------
 gcc/edit-context.h          |  96 ++++++++++++++++++++++++++++-
 3 files changed, 159 insertions(+), 118 deletions(-)

diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index f6bfcc9..45c7a56 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "backtrace.h"
 #include "diagnostic.h"
 #include "diagnostic-color.h"
+#include "edit-context.h"
 #include "selftest.h"
 
 #ifdef HAVE_TERMIOS_H
@@ -240,6 +241,7 @@ class layout
   expanded_location m_exploc;
   colorizer m_colorizer;
   bool m_colorize_source_p;
+  edit_context m_edit;
   auto_vec <layout_range> m_layout_ranges;
   auto_vec <const fixit_hint *> m_fixit_hints;
   auto_vec <line_span> m_line_spans;
@@ -766,6 +768,7 @@ layout::layout (diagnostic_context * context,
   m_exploc (richloc->get_expanded_location (0)),
   m_colorizer (context, diagnostic_kind),
   m_colorize_source_p (context->colorize_source_p),
+  m_edit (),
   m_layout_ranges (richloc->get_num_locations ()),
   m_fixit_hints (richloc->get_num_fixit_hints ()),
   m_line_spans (1 + richloc->get_num_locations ()),
@@ -873,6 +876,13 @@ layout::layout (diagnostic_context * context,
 
   if (context->show_ruler_p)
     show_ruler (m_x_offset + max_width);
+
+  /* Determine effect of fixits on the lines.  */
+  for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
+    {
+      const fixit_hint *hint = m_fixit_hints[i];
+      m_edit.add_fixit (hint);
+    }
 }
 
 /* Return true iff we should print a heading when starting the
@@ -1257,7 +1267,32 @@ layout::annotation_line_showed_range_p (int line, int start_column,
 void
 layout::print_any_fixits (int row)
 {
+  edited_file *file = m_edit.get_file (m_exploc.file);
+  if (!file)
+    return;
+  edited_line *line = file->get_line (row);
+  if (!line)
+    return;
+
   int column = 0;
+
+#if 0
+  /* TODO: print the subset of the changed line thats
+     changed, or covered by columns in the ranges...
+     remapping to post-change columns.  */
+
+  int first_column = 1;
+  int last_column = 10;
+
+  move_to_column (&column, first_column);
+  const char *content = line->get_content ();
+  m_colorizer.set_fixit_insert ();
+  for (int column = 1; column <= last_column; column++)
+    pp_character (m_pp, content[column - 1]);
+  m_colorizer.set_normal_text ();
+  return;
+#endif
+
   for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
     {
       const fixit_hint *hint = m_fixit_hints[i];
diff --git a/gcc/edit-context.c b/gcc/edit-context.c
index 5945f42..8bf2b7c 100644
--- a/gcc/edit-context.c
+++ b/gcc/edit-context.c
@@ -39,104 +39,6 @@ along with GCC; see the file COPYING3.  If not see
    The "filename" params are required to outlive the edit_context (no
    copy of the underlying str is taken, just the ptr).  */
 
-/* Forward decls.  class edit_context is declared within edit-context.h.
-   The other types are declared here.  */
-class edit_context;
-class edited_file;
-class edited_line;
-class line_event;
-  class insert_event;
-  class replace_event;
-
-/* A struct to hold the params of a print_diff call.  */
-
-struct diff
-{
-  diff (pretty_printer *pp, bool show_filenames)
-  : m_pp (pp), m_show_filenames (show_filenames) {}
-
-  pretty_printer *m_pp;
-  bool m_show_filenames;
-};
-
-/* The state of one named file within an edit_context: the filename,
-   and the lines that have been edited so far.  */
-
-class edited_file
-{
- public:
-  edited_file (const char *filename);
-  static void delete_cb (edited_file *file);
-
-  const char *get_filename () const { return m_filename; }
-  char *get_content ();
-
-  bool apply_insert (int line, int column, const char *str, int len);
-  bool apply_replace (int line, int start_column,
-		      int finish_column,
-		      const char *replacement_str,
-		      int replacement_len);
-  int get_effective_column (int line, int column);
-
-  static int call_print_diff (const char *, edited_file *file,
-			      void *user_data)
-  {
-    diff *d = (diff *)user_data;
-    file->print_diff (d->m_pp, d->m_show_filenames);
-    return 0;
-  }
-
- private:
-  bool print_content (pretty_printer *pp);
-  void print_diff (pretty_printer *pp, bool show_filenames);
-  void print_diff_hunk (pretty_printer *pp, int start_of_hunk,
-			int end_of_hunk);
-  void print_diff_line (pretty_printer *pp, char prefix_char,
-			const char *line, int line_size);
-  edited_line *get_line (int line);
-  edited_line *get_or_insert_line (int line);
-  int get_num_lines (bool *missing_trailing_newline);
-
-  const char *m_filename;
-  typed_splay_tree<int, edited_line *> m_edited_lines;
-  int m_num_lines;
-};
-
-/* The state of one edited line within an edited_file.
-   As well as the current content of the line, it contains a record of
-   the changes, so that further changes can be applied in the correct
-   place.  */
-
-class edited_line
-{
- public:
-  edited_line (const char *filename, int line_num);
-  ~edited_line ();
-  static void delete_cb (edited_line *el);
-
-  int get_line_num () const { return m_line_num; }
-  const char *get_content () const { return m_content; }
-  int get_len () const { return m_len; }
-
-  int get_effective_column (int orig_column) const;
-  bool apply_insert (int column, const char *str, int len);
-  bool apply_replace (int start_column,
-		      int finish_column,
-		      const char *replacement_str,
-		      int replacement_len);
-
- private:
-  void ensure_capacity (int len);
-  void ensure_terminated ();
-  void print_content (pretty_printer *pp) const;
-
-  int m_line_num;
-  char *m_content;
-  int m_len;
-  int m_alloc_sz;
-  auto_vec <line_event *> m_line_events;
-};
-
 /* Abstract base class for representing events that have occurred
    on one line of one file.  */
 
@@ -221,28 +123,38 @@ edit_context::add_fixits (rich_location *richloc)
   for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
     {
       const fixit_hint *hint = richloc->get_fixit_hint (i);
-      switch (hint->get_kind ())
+      if (!add_fixit (hint))
+	return;
+    }
+}
+
+/* FIXME.  */
+
+bool
+edit_context::add_fixit (const fixit_hint *hint)
+{
+  switch (hint->get_kind ())
+    {
+    case fixit_hint::INSERT:
+      if (!apply_insert ((const fixit_insert *)hint))
 	{
-	case fixit_hint::INSERT:
-	  if (!apply_insert ((const fixit_insert *)hint))
-	    {
-	      /* Failure.  */
-	      m_valid = false;
-	      return;
-	    }
-	  break;
-	case fixit_hint::REPLACE:
-	  if (!apply_replace ((const fixit_replace *)hint))
-	    {
-	      /* Failure.  */
-	      m_valid = false;
-	      return;
-	    }
-	  break;
-	default:
-	  gcc_unreachable ();
+	  /* Failure.  */
+	  m_valid = false;
+	  return false;
 	}
+      break;
+    case fixit_hint::REPLACE:
+      if (!apply_replace ((const fixit_replace *)hint))
+	{
+	  /* Failure.  */
+	  m_valid = false;
+	  return false;
+	}
+      break;
+    default:
+      gcc_unreachable ();
     }
+  return true;
 }
 
 /* Get the content of the given file, with fix-its applied.
diff --git a/gcc/edit-context.h b/gcc/edit-context.h
index 842da56..c2a6b62 100644
--- a/gcc/edit-context.h
+++ b/gcc/edit-context.h
@@ -24,6 +24,8 @@ along with GCC; see the file COPYING3.  If not see
 
 class edit_context;
 class edited_file;
+class edited_line;
+class line_event;
 
 /* A set of changes to the source code.
 
@@ -47,6 +49,7 @@ class edit_context
   bool valid_p () const { return m_valid; }
 
   void add_fixits (rich_location *richloc);
+  bool add_fixit (const fixit_hint *hint);
 
   char *get_content (const char *filename);
 
@@ -55,14 +58,105 @@ class edit_context
   char *generate_diff (bool show_filenames);
   void print_diff (pretty_printer *pp, bool show_filenames);
 
+  edited_file *get_file (const char *filename);
+
  private:
   bool apply_insert (const fixit_insert *insert);
   bool apply_replace (const fixit_replace *replace);
-  edited_file *get_file (const char *filename);
   edited_file &get_or_insert_file (const char *filename);
 
   bool m_valid;
   typed_splay_tree<const char *, edited_file *> m_files;
 };
 
+/* A struct to hold the params of a print_diff call.  */
+
+struct diff
+{
+  diff (pretty_printer *pp, bool show_filenames)
+  : m_pp (pp), m_show_filenames (show_filenames) {}
+
+  pretty_printer *m_pp;
+  bool m_show_filenames;
+};
+
+/* The state of one named file within an edit_context: the filename,
+   and the lines that have been edited so far.  */
+
+class edited_file
+{
+ public:
+  edited_file (const char *filename);
+  static void delete_cb (edited_file *file);
+
+  const char *get_filename () const { return m_filename; }
+  char *get_content ();
+
+  bool apply_insert (int line, int column, const char *str, int len);
+  bool apply_replace (int line, int start_column,
+		      int finish_column,
+		      const char *replacement_str,
+		      int replacement_len);
+  int get_effective_column (int line, int column);
+
+  static int call_print_diff (const char *, edited_file *file,
+			      void *user_data)
+  {
+    diff *d = (diff *)user_data;
+    file->print_diff (d->m_pp, d->m_show_filenames);
+    return 0;
+  }
+
+  edited_line *get_line (int line);
+
+ private:
+  bool print_content (pretty_printer *pp);
+  void print_diff (pretty_printer *pp, bool show_filenames);
+  void print_diff_hunk (pretty_printer *pp, int start_of_hunk,
+			int end_of_hunk);
+  void print_diff_line (pretty_printer *pp, char prefix_char,
+			const char *line, int line_size);
+  edited_line *get_or_insert_line (int line);
+  int get_num_lines (bool *missing_trailing_newline);
+
+  const char *m_filename;
+  typed_splay_tree<int, edited_line *> m_edited_lines;
+  int m_num_lines;
+};
+
+/* The state of one edited line within an edited_file.
+   As well as the current content of the line, it contains a record of
+   the changes, so that further changes can be applied in the correct
+   place.  */
+
+class edited_line
+{
+ public:
+  edited_line (const char *filename, int line_num);
+  ~edited_line ();
+  static void delete_cb (edited_line *el);
+
+  int get_line_num () const { return m_line_num; }
+  const char *get_content () const { return m_content; }
+  int get_len () const { return m_len; }
+
+  int get_effective_column (int orig_column) const;
+  bool apply_insert (int column, const char *str, int len);
+  bool apply_replace (int start_column,
+		      int finish_column,
+		      const char *replacement_str,
+		      int replacement_len);
+
+ private:
+  void ensure_capacity (int len);
+  void ensure_terminated ();
+  void print_content (pretty_printer *pp) const;
+
+  int m_line_num;
+  char *m_content;
+  int m_len;
+  int m_alloc_sz;
+  auto_vec <line_event *> m_line_events;
+};
+
 #endif /* GCC_EDIT_CONTEXT_H.  */
-- 
1.8.5.3

