/* Implementation of gcc_rich_location class
   Copyright (C) 2014-2018 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "hash-set.h"
#include "vec.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "inchash.h"
#include "tree-core.h"
#include "tree.h"
#include "diagnostic-core.h"
#include "gcc-rich-location.h"
#include "print-tree.h"
#include "pretty-print.h"
#include "intl.h"
#include "cpplib.h"
#include "diagnostic.h"

/* Add a range to the rich_location, covering expression EXPR,
   using LABEL if non-NULL. */

void
gcc_rich_location::add_expr (tree expr, range_label *label)
{
  gcc_assert (expr);

  if (CAN_HAVE_RANGE_P (expr))
    add_range (EXPR_LOCATION (expr), SHOW_RANGE_WITHOUT_CARET, label);
}

/* If T is an expression, add a range for it to the rich_location,
   using LABEL if non-NULL. */

void
gcc_rich_location::maybe_add_expr (tree t, range_label *label)
{
  if (EXPR_P (t))
    add_expr (t, label);
}

/* Add a fixit hint suggesting replacing the range at MISSPELLED_TOKEN_LOC
   with the identifier HINT_ID.  */

void
gcc_rich_location::add_fixit_misspelled_id (location_t misspelled_token_loc,
					    tree hint_id)
{
  gcc_assert (TREE_CODE (hint_id) == IDENTIFIER_NODE);

  add_fixit_replace (misspelled_token_loc, IDENTIFIER_POINTER (hint_id));
}

/* Return true if there is nothing on LOC's line before LOC.  */

static bool
blank_line_before_p (location_t loc)
{
  expanded_location exploc = expand_location (loc);
  char_span line = location_get_source_line (exploc.file, exploc.line);
  if (!line)
    return false;
  if (line.length () < (size_t)exploc.column)
    return false;
  /* Columns are 1-based.  */
  for (int column = 1; column < exploc.column; ++column)
    if (!ISSPACE (line[column - 1]))
      return false;
  return true;
}

/* Subroutine of gcc_rich_location::add_fixit_insert_formatted.
   Return true if we should add the content on its own line,
   false otherwise.
   If true is returned then *OUT_START_OF_LINE is written to.  */

static bool
use_new_line (location_t insertion_point, location_t indent,
	      location_t *out_start_of_line)
{
  if (indent == UNKNOWN_LOCATION)
    return false;
  const line_map *indent_map = linemap_lookup (line_table, indent);
  if (linemap_macro_expansion_map_p (indent_map))
    return false;

  if (!blank_line_before_p (insertion_point))
    return false;

  /* Locate the start of the line containing INSERTION_POINT.  */
  const line_map *insertion_point_map
    = linemap_lookup (line_table, insertion_point);
  if (linemap_macro_expansion_map_p (insertion_point_map))
    return false;
  const line_map_ordinary *ordmap
    = linemap_check_ordinary (insertion_point_map);
  expanded_location exploc_insertion_point = expand_location (insertion_point);
  location_t start_of_line
    = linemap_position_for_line_and_column (line_table, ordmap,
					    exploc_insertion_point.line, 1);
  *out_start_of_line = start_of_line;
  return true;
}

/* Add a fix-it hint suggesting the insertion of CONTENT before
   INSERTION_POINT.

   Attempt to handle formatting: if INSERTION_POINT is the first thing on
   its line, and INDENT is sufficiently sane, then add CONTENT on its own
   line, using the indentation of INDENT.
   Otherwise, add CONTENT directly before INSERTION_POINT.

   For example, adding "CONTENT;" with the closing brace as the insertion
   point and "INDENT;" as the indentation point:

   if ()
     {
       INDENT;
     }

  would lead to:

   if ()
     {
       INDENT;
       CONTENT;
     }

  but adding it to:

    if () {INDENT;}

  would lead to:

    if () {INDENT;CONTENT;}
*/

void
gcc_rich_location::add_fixit_insert_formatted (const char *content,
					       location_t insertion_point,
					       location_t indent)
{
  location_t start_of_line;
  if (use_new_line (insertion_point, indent, &start_of_line))
    {
      /* Add CONTENT on its own line, using the indentation of INDENT.  */

      /* Generate an insertion string, indenting by the amount INDENT
	 was indented.  */
      int indent_column = LOCATION_COLUMN (get_start (indent));
      pretty_printer tmp_pp;
      pretty_printer *pp = &tmp_pp;
      /* Columns are 1-based.  */
      for (int column = 1; column < indent_column; ++column)
	pp_space (pp);
      pp_string (pp, content);
      pp_newline (pp);

      add_fixit_insert_before (start_of_line, pp_formatted_text (pp));
    }
  else
    add_fixit_insert_before (insertion_point, content);
}
