From 508c392c7c231281c83e0e4e3dd48ad361e002d8 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 14 Jun 2017 09:50:06 -0400
Subject: [PATCH 25/44] FIXME: add param spellcheck-comments-max-suggestions,
 defaulting to 1

---
 gcc/doc/invoke.texi                                |  8 ++++
 gcc/params.def                                     |  6 +++
 gcc/spellcheck-enchant.c                           | 54 ++++++++++++++++------
 .../c-c++-common/Wspellcheck-comments-1.c          | 13 ++----
 .../c-c++-common/Wspellcheck-comments-2.c          | 15 +++---
 .../c-c++-common/Wspellcheck-comments-5.c          |  3 +-
 .../c-c++-common/Wspellcheck-comments-8.c          | 10 ++++
 7 files changed, 77 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/Wspellcheck-comments-8.c

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 0714343..50f7418 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -4639,6 +4639,10 @@ Warn about words in comments that may be misspelled.
 This warning is only available if GCC was configured with the Enchant
 spellchecking library (via @option{--with-enchant}).
 
+By default, at most one suggestion will be offered for each misspelled
+word.  Additional suggestions can be seen by adjusting via
+@option{--param spellcheck-comments-max-suggestions=@var{value}}.
+
 The option @option{-Wspellcheck-comments=} selects with human language
 to use (e.g. @code{en_GB}).
 
@@ -10634,6 +10638,10 @@ we may be able to devirtualize speculatively.
 @item max-vrp-switch-assertions
 The maximum number of assertions to add along the default edge of a switch
 statement during VRP.  The default is 10.
+
+@item spellcheck-comments-max-suggestions
+The maximum number of suggestions to offer when @option{-Wspellcheck-comments}
+detects a spelling mistake in a comment.  The default is 1.
 @end table
 @end table
 
diff --git a/gcc/params.def b/gcc/params.def
index 6b07518..4258073 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1280,6 +1280,12 @@ DEFPARAM (PARAM_VECT_EPILOGUES_NOMASK,
 	  "Enable loop epilogue vectorization using smaller vector size.",
 	  0, 0, 1)
 
+DEFPARAM (PARAM_SPELLCHECK_COMMENTS_MAX_SUGGESTIONS,
+	  "spellcheck-comments-max-suggestions",
+	  "Maximum number of suggestions to offer when spellchecking"
+	  " comments.",
+	  1, 0, 100)
+
 /*
 
 Local variables:
diff --git a/gcc/spellcheck-enchant.c b/gcc/spellcheck-enchant.c
index 73a8db8..2d15d26 100644
--- a/gcc/spellcheck-enchant.c
+++ b/gcc/spellcheck-enchant.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "cpplib.h"
 #include "selftest.h"
+#include "params.h"
 
 /* This file is guarded by "#ifdef HAVE_ENCHANT".  */
 
@@ -45,6 +46,9 @@ class suggestions
     : m_dict (dict), m_suggestions (NULL)
     {
       m_suggestions = enchant_dict_suggest (m_dict, word, len, &m_num);
+      if (m_num
+	  > (size_t)PARAM_VALUE (PARAM_SPELLCHECK_COMMENTS_MAX_SUGGESTIONS))
+	m_num = PARAM_VALUE (PARAM_SPELLCHECK_COMMENTS_MAX_SUGGESTIONS);
     }
   ~suggestions ()
     {
@@ -273,26 +277,48 @@ spellcheck_word (const unsigned char *word, size_t len,
 
   location_t word_loc = make_word_location (ord_map, line, column, len);
 
-  if (warning_at (word_loc, OPT_Wspellcheck_comments_,
-		  "possible spelling mistake in comment: %q.*s",
-		  (int)len, word))
+  suggestions s
+    = checker::singleton->get_suggestions ((const char *)word, len);
+
+  /* Issue a warning, potentially with suggestions.
+     If there's just one suggestion, combine it with the warning, to
+     minimize the diagnostic spew.  */
+  if (s.get_count () > 1)
     {
-      suggestions s
-	= checker::singleton->get_suggestions ((const char *)word, len);
-      for (size_t i = 0; i < s.get_count (); i++)
+      /* Multiple suggestions.  */
+      if (warning_at (word_loc, OPT_Wspellcheck_comments_,
+		      "possible spelling mistake in comment: %q.*s",
+		      (int)len, word))
 	{
-	  rich_location richloc (line_table, word_loc);
-	  richloc.add_fixit_replace (s.get_suggestion (i));
+	  for (size_t i = 0; i < s.get_count (); i++)
+	    {
+	      rich_location richloc (line_table, word_loc);
+	      richloc.add_fixit_replace (s.get_suggestion (i));
 
-	  /* If there's more than one suggestion, then the
-	     suggestions are mutually exclusive.  */
-	  if (s.get_count () > 1)
-	    richloc.fixits_cannot_be_auto_applied ();
+	      /* If there's more than one suggestion, then the
+		 suggestions are mutually exclusive.  */
+	      richloc.fixits_cannot_be_auto_applied ();
 
-	  inform_at_rich_loc (&richloc, "suggestion: %qs",
-			      s.get_suggestion (i));
+	      inform_at_rich_loc (&richloc, "suggestion: %qs",
+				  s.get_suggestion (i));
+	    }
 	}
     }
+  else if (s.get_count () == 1)
+    {
+      /* One suggestion.  */
+      rich_location richloc (line_table, word_loc);
+      richloc.add_fixit_replace (s.get_suggestion (0));
+      warning_at_rich_loc (&richloc, OPT_Wspellcheck_comments_,
+			   "possible spelling mistake in comment: %q.*s;"
+			   " did you mean %qs?",
+			   (int)len, word, s.get_suggestion (0));
+    }
+ else
+   /* No suggestions.  */
+   warning_at (word_loc, OPT_Wspellcheck_comments_,
+	       "possible spelling mistake in comment: %q.*s",
+	       (int)len, word);
 }
 
 /* Initialize this module, using the given LANGUAGE_TAG as the
diff --git a/gcc/testsuite/c-c++-common/Wspellcheck-comments-1.c b/gcc/testsuite/c-c++-common/Wspellcheck-comments-1.c
index d4e6b49..d360c75 100644
--- a/gcc/testsuite/c-c++-common/Wspellcheck-comments-1.c
+++ b/gcc/testsuite/c-c++-common/Wspellcheck-comments-1.c
@@ -2,21 +2,16 @@
 /* { dg-options "-Wspellcheck-comments" }  */
 
 /* When NONCONST_PRED is false the code will evaulate to constant.  */
-/* { dg-warning "46: possible spelling mistake in comment: 'evaulate'" "" { target *-*-* } .-1 } */
-/* { dg-message "46: suggestion: 'evaluate'" "" { target *-*-* } .-2 } */
-/* There may be other suggestions in each of these cases.  */
+/* { dg-warning "46: possible spelling mistake in comment: 'evaulate'; did you mean 'evaluate'?" "" { target *-*-* } .-1 } */
 
 // Example of a boogus C++-style comment
-/* { dg-warning "17: possible spelling mistake in comment: 'boogus'" "" { target *-*-* } .-1 } */
-/* { dg-message "17: suggestion: 'bogus'" "" { target *-*-* } .-2 } */
+/* { dg-warning "17: possible spelling mistake in comment: 'boogus'; did you mean 'bogus'?" "" { target *-*-* } .-1 } */
 
 /* Exercise the code path for the final word in a commment*/
-/* { dg-warning "51: possible spelling mistake in comment: 'commment'" "" { target *-*-* } .-1 } */
-/* { dg-message "51: suggestion: 'comment'" "" { target *-*-* } .-2 } */
+/* { dg-warning "51: possible spelling mistake in comment: 'commment'; did you mean 'comment'?" "" { target *-*-* } .-1 } */
 
 // Exercise the code path for the final word in a C++ commment
-/* { dg-warning "55: possible spelling mistake in comment: 'commment'" "" { target *-*-* } .-1 } */
-/* { dg-message "55: suggestion: 'comment'" "" { target *-*-* } .-2 } */
+/* { dg-warning "55: possible spelling mistake in comment: 'commment'; did you mean 'comment'?" "" { target *-*-* } .-1 } */
 
 /* Examples of words that are correctly spelled, containing apostrophes:
    don't doesn't is isn't.  */
diff --git a/gcc/testsuite/c-c++-common/Wspellcheck-comments-2.c b/gcc/testsuite/c-c++-common/Wspellcheck-comments-2.c
index 10c1825..9391d34 100644
--- a/gcc/testsuite/c-c++-common/Wspellcheck-comments-2.c
+++ b/gcc/testsuite/c-c++-common/Wspellcheck-comments-2.c
@@ -1,14 +1,15 @@
 /* { dg-require-enchant "" } */
 /* { dg-options "-Wspellcheck-comments -fdiagnostics-show-caret" } */
 
-/* Verify that misspelled words are underlined correctly.  We need
-   a word that the checker won't offer a suggestion for, to avoid
-   having to specify checker output within the test case.
-   Hence the use of splendiferouslitudinalistic here.  */
+/* Verify that misspelled words are underlined correctly, and that fix-it
+   hints are offered.  */
+
+/* evaulate.  */
 #if 0
-{ dg-warning "possible spelling mistake in comment: 'splendiferouslitudinalistic'" "" { target *-*-* } .-2 }
+{ dg-warning "possible spelling mistake in comment: 'evaulate'; did you mean 'evaluate'" "" { target *-*-* } .-2 }
 { dg-begin-multiline-output "" }
-    Hence the use of splendiferouslitudinalistic here.
-                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
+ /* evaulate.  */
+    ^~~~~~~~
+    evaluate
 { dg-end-multiline-output "" }
 #endif
diff --git a/gcc/testsuite/c-c++-common/Wspellcheck-comments-5.c b/gcc/testsuite/c-c++-common/Wspellcheck-comments-5.c
index 0f6fa8e..a042446 100644
--- a/gcc/testsuite/c-c++-common/Wspellcheck-comments-5.c
+++ b/gcc/testsuite/c-c++-common/Wspellcheck-comments-5.c
@@ -2,5 +2,4 @@
 /* { dg-require-enchant "" } */
 /* { dg-options "-Wspellcheck-comments=en_GB" } */
 // Is it color or colour?
-// { dg-warning "possible spelling mistake in comment: 'color'" "" { target *-*-* } .-1 }
-// { dg-message "suggestion: 'colour'" "" { target *-*-* } .-2 }
+// { dg-warning "possible spelling mistake in comment: 'color'; did you mean 'colour'" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/c-c++-common/Wspellcheck-comments-8.c b/gcc/testsuite/c-c++-common/Wspellcheck-comments-8.c
new file mode 100644
index 0000000..0038196
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wspellcheck-comments-8.c
@@ -0,0 +1,10 @@
+/* Test of multiple suggestions.  */
+/* { dg-require-enchant "" } */
+/* { dg-options "-Wspellcheck-comments --param spellcheck-comments-max-suggestions=10" }  */
+
+/* When NONCONST_PRED is false the code will evaulate to constant.  */
+/* { dg-warning "46: possible spelling mistake in comment: 'evaulate'" "" { target *-*-* } .-1 } */
+/* { dg-message "46: suggestion: 'evaluate'" "" { target *-*-* } .-2 } */
+/* { dg-message "46: suggestion: 'ululate'" "" { target *-*-* } .-3 } */
+/* { dg-message "46: suggestion: 'elevate'" "" { target *-*-* } .-4 } */
+/* ...and there may be other suggestions.  */
-- 
1.8.5.3

