diff options
author | David Malcolm <dmalcolm@redhat.com> | 2017-05-01 19:15:36 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2017-05-01 19:15:36 +0000 |
commit | 338035aa194405df94875cebb389d593cf9ef00a (patch) | |
tree | ec2f1379d4ea93aebee73e038601a72813231176 /libcpp/include/line-map.h | |
parent | 4d82d0bc4350ce18a5fb64049d24e98dee1235f9 (diff) | |
download | gcc-338035aa194405df94875cebb389d593cf9ef00a.zip gcc-338035aa194405df94875cebb389d593cf9ef00a.tar.gz gcc-338035aa194405df94875cebb389d593cf9ef00a.tar.bz2 |
Eliminate fixit_hint class hierarchy
The original implementation of fix-it hints (r230674) had an abstract
base class "fixit_hint" and three subclasses, representing
each of insertions, replacements, and deletions.
Having multiple classes for fix-it hints was a nuisance, as it required
per-class logic everywhere that the hints were handled.
In r239632 I eliminated the deletion subclass in favor of replacement
with the empty string (two subclasses are easier than three).
This patch eliminates the class hierarchy altogether by implementing
insertion in terms of replacement, by representing replacements via
a half-open interval (so that for an insertion, start == next location,
and we're effectively replacing an empty range at the insertion point
with the new string).
This greatly simplifies the code for handling fix-it hints; for example
it allows removal of a parallel class hierarchy of line_event within
edit-context.c.
It also improves consolidation of hints: we can now consolidate
insertions at the same location, affecting a couple of tests
(selftest::test_one_liner_many_fixits and
gcc.dg/Wmissing-braces-fixits.c).
gcc/ChangeLog:
* diagnostic-show-locus.c (layout::get_expanded_location): Rewrite
to use new fixit_hint representation, using the "replace" logic.
(get_line_span_for_fixit_hint): Likewise.
(layout::print_any_fixits): Likewise.
(selftest::test_one_liner_many_fixits): Rename to...
(selftest::test_one_liner_many_fixits_1): ...this, and update
comment and expected output to reflect that the multiple fix-it
hints are now consolidated into one insertion.
(selftest::test_one_liner_many_fixits_2): New test.
(selftest::test_diagnostic_show_locus_one_liner): Update for
above.
(selftest::test_fixit_consolidation): Update for fix-it API
change.
* diagnostic.c (print_parseable_fixits): Likewise.
* edit-context.c (edited_line::m_line_events): Convert from
auto_vec <line_event *> to auto_vec <line_event>.
(class line_event): Convert from abstract base class to a concrete
class, taking over the role of replace_event.
(class insert_event): Delete.
(class replace_event): Rename to class line_event. Convert to
half-open range.
(edit_context::add_fixits): Reimplement.
(edit_context::apply_insert): Delete.
(edit_context::apply_replace): Rename to...
(edit_context::apply_fixit): ...this. Convert to half-open range.
(edited_file::apply_insert): Delete.
(edited_file::apply_replace): Rename to...
(edited_file::apply_fixit): ...this.
(edited_line::~edited_line): Drop deletion of events.
(edited_line::apply_insert): Delete.
(edited_line::apply_replace): Rename to...
(edited_line::apply_fixit): ...this. Convert to half-open range.
Update for change to type of m_line_events.
* edit-context.h (edit_context::apply_insert): Delete.
(edit_context::apply_replace): Rename to...
(edit_context::apply_fixit): ...this.
gcc/testsuite/ChangeLog:
* gcc.dg/Wmissing-braces-fixits.c: Update expected output to
reflect insertion fix-it hints at the same location now being
consolidated.
libcpp/ChangeLog:
* include/line-map.h (source_range::intersects_line_p): Delete.
(rich_location::add_fixit): Delete.
(rich_location::maybe_add_fixit): New method.
(class fixit_hint): Reimplement in terms of...
(class fixit_replace): ...this.
(class fixit_insert): Delete.
* line-map.c (linemap_position_for_loc_and_offset): Drop overzealous
linemap_assert_fails.
(source_range::intersects_line_p): Rename to...
(fixit_hint::affects_line_p): New function.
(rich_location::add_fixit_insert_before): Reimplement in terms of
maybe_add_fixit, moving validation there.
(rich_location::add_fixit_insert_after): Likewise.
(column_before_p): Delete.
(rich_location::add_fixit_replace): Reimplement in terms of
maybe_add_fixit, moving validation there. Convert closed input range
to half-open range.
(rich_location::add_fixit): Delete.
(rich_location::maybe_add_fixit): New function.
(fixit_insert::fixit_insert): Delete.
(fixit_insert::~fixit_insert): Delete.
(fixit_insert::affects_line_p): Delete.
(fixit_insert::maybe_append_replace): Delete.
(fixit_replace::fixit_replace): Rename to...
(fixit_hint::fixit_hint): ...this, rewriting as necessary.
(fixit_replace::~fixit_replace): Delete.
(fixit_replace::affects_line_p): Delete.
(fixit_replace::maybe_append_replace): Rename to...
(fixit_hint::maybe_append): ...this, rewriting as necessary.
From-SVN: r247445
Diffstat (limited to 'libcpp/include/line-map.h')
-rw-r--r-- | libcpp/include/line-map.h | 90 |
1 files changed, 28 insertions, 62 deletions
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 522e8bb..0c44f01 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -305,9 +305,6 @@ struct GTY(()) source_range result.m_finish = finish; return result; } - - /* Is there any part of this range on the given line? */ - bool intersects_line_p (const char *file, int line) const; }; /* Memory allocation function typedef. Works like xrealloc. */ @@ -1416,8 +1413,6 @@ semi_embedded_vec<T, NUM_EMBEDDED>::truncate (int len) } class fixit_hint; - class fixit_insert; - class fixit_replace; /* A "rich" source code location, for use when printing diagnostics. A rich_location has one or more carets&ranges, where the carets @@ -1667,7 +1662,9 @@ class rich_location private: bool reject_impossible_fixit (source_location where); void stop_supporting_fixits (); - void add_fixit (fixit_hint *hint); + void maybe_add_fixit (source_location start, + source_location next_loc, + const char *new_content); public: static const int STATICALLY_ALLOCATED_RANGES = 3; @@ -1687,72 +1684,41 @@ protected: bool m_seen_impossible_fixit; }; -class fixit_hint -{ -public: - enum kind {INSERT, REPLACE}; - - virtual ~fixit_hint () {} - - virtual enum kind get_kind () const = 0; - virtual bool affects_line_p (const char *file, int line) const = 0; - virtual source_location get_start_loc () const = 0; - virtual bool maybe_get_end_loc (source_location *out) const = 0; - /* Vfunc for consolidating successor fixits. */ - virtual bool maybe_append_replace (line_maps *set, - source_range src_range, - const char *new_content) = 0; -}; - -class fixit_insert : public fixit_hint -{ - public: - fixit_insert (source_location where, - const char *new_content); - ~fixit_insert (); - enum kind get_kind () const { return INSERT; } - bool affects_line_p (const char *file, int line) const; - source_location get_start_loc () const { return m_where; } - bool maybe_get_end_loc (source_location *) const { return false; } - bool maybe_append_replace (line_maps *set, - source_range src_range, - const char *new_content); - - source_location get_location () const { return m_where; } - const char *get_string () const { return m_bytes; } - size_t get_length () const { return m_len; } +/* A fix-it hint: a suggested insertion, replacement, or deletion of text. + We handle these three types of edit with one class, by representing + them as replacement of a half-open range: + [start, next_loc) + Insertions have start == next_loc: "replace" the empty string at the + start location with the new string. + Deletions are replacement with the empty string. */ - private: - source_location m_where; - char *m_bytes; - size_t m_len; -}; - -class fixit_replace : public fixit_hint +class fixit_hint { public: - fixit_replace (source_range src_range, - const char *new_content); - ~fixit_replace (); + fixit_hint (source_location start, + source_location next_loc, + const char *new_content); + ~fixit_hint () { free (m_bytes); } - enum kind get_kind () const { return REPLACE; } bool affects_line_p (const char *file, int line) const; - source_location get_start_loc () const { return m_src_range.m_start; } - bool maybe_get_end_loc (source_location *out) const - { - *out = m_src_range.m_finish; - return true; - } - bool maybe_append_replace (line_maps *set, - source_range src_range, - const char *new_content); + source_location get_start_loc () const { return m_start; } + source_location get_next_loc () const { return m_next_loc; } + bool maybe_append (source_location start, + source_location next_loc, + const char *new_content); - source_range get_range () const { return m_src_range; } const char *get_string () const { return m_bytes; } size_t get_length () const { return m_len; } + bool insertion_p () const { return m_start == m_next_loc; } + private: - source_range m_src_range; + /* We don't use source_range here since, unlike most places, + this is a half-open/half-closed range: + [start, next_loc) + so that we can support insertion via start == next_loc. */ + source_location m_start; + source_location m_next_loc; char *m_bytes; size_t m_len; }; |