This is an archive of the discontinued LLVM Phabricator instance.

Fix OptTable::findNearest() adding delimiter for free
ClosedPublic

Authored by thakis on May 1 2019, 5:51 AM.

Details

Summary

Prior to this, OptTable::findNearest() thought that the input --foo had an editing distance of 0 from an existing flag --foo=, which made it suggest flags with delimiters more often than flags without one. After this, it correctly assigns this case an editing distance of 1.

Diff Detail

Repository
rL LLVM

Event Timeline

thakis created this revision.May 1 2019, 5:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 1 2019, 5:51 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
MaskRay accepted this revision.May 1 2019, 7:07 AM
MaskRay added inline comments.
llvm/lib/Option/OptTable.cpp
294 ↗(On Diff #197531)

How about:

StringRef LHS, RHS;
char Last = CandidateName.back();
std::string NormalizedName = Option;
if (Last == '=' || Last == ':') {
  std::tie(LHS, RHS) = Option.split(Last);
  NormalizedName = LHS;
  if (Option.find(Last) == LHS.size())
    NormalizedName += Last;
}
llvm/unittests/Option/OptionParsingTest.cpp
301 ↗(On Diff #197531)

// --glormp should have an editing distance of 1 to --glormp=.

This revision is now accepted and ready to land.May 1 2019, 7:07 AM
thakis updated this revision to Diff 197545.May 1 2019, 7:28 AM
thakis marked 3 inline comments as done.

address comments

thakis added a comment.May 1 2019, 7:28 AM

Thanks for the fast review!

llvm/lib/Option/OptTable.cpp
294 ↗(On Diff #197531)

I like it.

But in a follow-up, I wanted to add the following the the loop below:

if (RHS.empty() && !Delimiter.empty()) {
  // 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:`
  // since the latter would need an argument, even though both have
  // an unmodified editing distance of 1.
  Distance++;
}

With Delimiter gone, that would become if (RHS.empty() && (Last == '=' || Last == ':') -- so I added a CandidateHasDelimiter variable too.

llvm/unittests/Option/OptionParsingTest.cpp
301 ↗(On Diff #197531)

Whoops! Thanks.

MaskRay accepted this revision.May 1 2019, 7:37 AM

Still looks good.

This revision was automatically updated to reflect the committed changes.