]> granicus.if.org Git - llvm/commitdiff
Option spell checking: Penalize delimiter flags if input has no argument
authorNico Weber <nicolasweber@gmx.de>
Wed, 1 May 2019 16:45:15 +0000 (16:45 +0000)
committerNico Weber <nicolasweber@gmx.de>
Wed, 1 May 2019 16:45:15 +0000 (16:45 +0000)
If the user passes a flag like `-version` to a program, it's more likely
they mean `--version` than `-version:`, since there's no parameter
passed. Hence, give delimited arguments a penalty of 1 if the user input
doesn't contain the delimiter or no data after it.

The motivation is that with this, lld-link can suggest "--version"
instead of "-version:" for "-version" and "-nodefaultlib" instead of
"-nodefaultlib:" for "-nodefaultlibs".

Differential Revision: https://reviews.llvm.org/D61382

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359701 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Option/OptTable.cpp
unittests/Option/OptionParsingTest.cpp
unittests/Option/Opts.td

index 47c5f80c7d70fc7a96c01902e6dd74861af7e41c..5833d03069f8688057e2e465429e47b47fb8b405 100644 (file)
@@ -301,6 +301,15 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString,
       unsigned Distance =
           CandidateRef.edit_distance(NormalizedName, /*AllowReplacements=*/true,
                                      /*MaxEditDistance=*/BestDistance);
+      if (RHS.empty() && CandidateHasDelimiter) {
+        // The Candidate ends with a = or : delimiter, but the option passed in
+        // didn't contain the delimiter (or doesn't have anything after it).
+        // In that case, penalize the correction: `-nodefaultlibs` is more
+        // likely to be a spello for `-nodefaultlib` than `-nodefaultlib:` even
+        // though both have an unmodified editing distance of 1, since the
+        // latter would need an argument.
+        ++Distance;
+      }
       if (Distance < BestDistance) {
         BestDistance = Distance;
         NearestString = (Candidate + RHS).str();
index ee741c25d059bdde44fd2e9dbbd3582e70d17328..e1d7a473ee7f23cf293c125b2311328ad1fc2c46 100644 (file)
@@ -298,10 +298,19 @@ TEST(Option, FindNearest) {
   EXPECT_EQ(1U, T.findNearest("/framb:foo", Nearest));
   EXPECT_EQ(Nearest, "/cramb:foo");
 
-  // `--glormp` should have an editing distance of 1 to `--glormp=`.
-  EXPECT_EQ(1U, T.findNearest("--glormp", Nearest));
-  EXPECT_EQ(Nearest, "--glormp=");
-  EXPECT_EQ(0U, T.findNearest("--glormp=foo", Nearest));
+  // `--glormp` should have an editing distance > 0 from `--glormp=`.
+  EXPECT_GT(T.findNearest("--glorrmp", Nearest), 0U);
+  EXPECT_EQ(Nearest, "--glorrmp=");
+  EXPECT_EQ(0U, T.findNearest("--glorrmp=foo", Nearest));
+
+  // `--blurmps` should correct to `--blurmp`, not `--blurmp=`, even though
+  // both naively have an editing distance of 1.
+  EXPECT_EQ(1U, T.findNearest("--blurmps", Nearest));
+  EXPECT_EQ(Nearest, "--blurmp");
+
+  // ...but `--blurmps=foo` should correct to `--blurmp=foo`.
+  EXPECT_EQ(1U, T.findNearest("--blurmps=foo", Nearest));
+  EXPECT_EQ(Nearest, "--blurmp=foo");
 
   // Flags should be included and excluded as specified.
   EXPECT_EQ(1U, T.findNearest("-doopf", Nearest, /*FlagsToInclude=*/OptFlag2));
index 231af4914d85bee40615c54d2d50fd821f38bf26..70920a6a76b440e35012b70e61eb0c79da564d15 100644 (file)
@@ -37,6 +37,9 @@ def Doopf2 : Flag<["-"], "doopf2">, HelpText<"The doopf2 option">, Flags<[OptFla
 def Ermgh : Joined<["--"], "ermgh">, HelpText<"The ermgh option">, MetaVarName<"ERMGH">, Flags<[OptFlag1]>;
 def Fjormp : Flag<["--"], "fjormp">, HelpText<"The fjormp option">, Flags<[OptFlag1]>;
 
-def Glormp_eq : Flag<["--"], "glormp=">;
+def Glorrmp_eq : Flag<["--"], "glorrmp=">;
+
+def Blurmpq : Flag<["--"], "blurmp">;
+def Blurmpq_eq : Flag<["--"], "blurmp=">;
 
 def DashDash : Option<["--"], "", KIND_REMAINING_ARGS>;