On May 8, 2013, at 12:42 PM, Dmitri Gribenko <[email protected]> wrote:
> On Wed, May 8, 2013 at 10:21 PM, Fariborz Jahanian <[email protected]> > wrote: >> Author: fjahanian >> Date: Wed May 8 14:21:00 2013 >> New Revision: 181458 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=181458&view=rev >> Log: >> documentation parsing. Patch to do typo correction for >> documentation commands. Patch was reviewed, along with >> great suggestions for improvement, by Doug. >> // rdar://12381408 >> >> Modified: >> cfe/trunk/include/clang/AST/CommentCommandTraits.h >> cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td >> cfe/trunk/lib/AST/CommentCommandTraits.cpp >> cfe/trunk/lib/AST/CommentLexer.cpp >> cfe/trunk/test/Sema/warn-documentation-fixits.cpp >> >> Modified: cfe/trunk/include/clang/AST/CommentCommandTraits.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentCommandTraits.h?rev=181458&r1=181457&r2=181458&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/CommentCommandTraits.h (original) >> +++ cfe/trunk/include/clang/AST/CommentCommandTraits.h Wed May 8 14:21:00 >> 2013 >> @@ -142,6 +142,8 @@ public: >> llvm_unreachable("the command should be known"); >> } >> >> + const CommandInfo *getTypoCorrectCommandInfo(StringRef Typo) const; >> + >> const CommandInfo *getCommandInfo(unsigned CommandID) const; >> >> const CommandInfo *registerUnknownCommand(StringRef CommandName); >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td?rev=181458&r1=181457&r2=181458&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td Wed May 8 >> 14:21:00 2013 >> @@ -159,5 +159,9 @@ def warn_verbatim_block_end_without_star >> def warn_unknown_comment_command_name : Warning< >> "unknown command tag name">, InGroup<Documentation>, DefaultIgnore; >> >> +def warn_correct_comment_command_name : Warning< >> + "unknown command tag name '%0'; did you mean '%1'?">, >> + InGroup<Documentation>; >> + >> } // end of documentation issue category >> } // end of AST component >> >> Modified: cfe/trunk/lib/AST/CommentCommandTraits.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentCommandTraits.cpp?rev=181458&r1=181457&r2=181458&view=diff >> ============================================================================== >> --- cfe/trunk/lib/AST/CommentCommandTraits.cpp (original) >> +++ cfe/trunk/lib/AST/CommentCommandTraits.cpp Wed May 8 14:21:00 2013 >> @@ -43,6 +43,33 @@ const CommandInfo *CommandTraits::getCom >> return getRegisteredCommandInfo(CommandID); >> } >> >> +const CommandInfo * >> +CommandTraits::getTypoCorrectCommandInfo(StringRef Typo) const { >> + const unsigned MaxEditDistance = 1; >> + unsigned BestEditDistance = MaxEditDistance + 1; >> + SmallVector<const CommandInfo *, 2> BestCommand; >> + >> + int NumOfCommands = sizeof(Commands) / sizeof(CommandInfo); >> + for (int i = 0; i < NumOfCommands; i++) { >> + StringRef Name = Commands[i].Name; > > This loop should also check dynamically registered commands. Ah, good catch. >> + unsigned MinPossibleEditDistance = abs((int)Name.size() - >> (int)Typo.size()); >> + if (MinPossibleEditDistance > 0 && >> + Typo.size() / MinPossibleEditDistance < 1) >> + continue; >> + unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance); >> + if (EditDistance > MaxEditDistance) >> + continue; >> + if (EditDistance == BestEditDistance) >> + BestCommand.push_back(&Commands[i]); >> + else if (EditDistance < BestEditDistance) { >> + BestCommand.clear(); >> + BestCommand.push_back(&Commands[i]); >> + BestEditDistance = EditDistance; >> + } >> + } >> + return (BestCommand.size() != 1) ? NULL : BestCommand[0]; >> +} >> + >> CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) >> { >> char *Name = Allocator.Allocate<char>(CommandName.size() + 1); >> memcpy(Name, CommandName.data(), CommandName.size()); >> >> Modified: cfe/trunk/lib/AST/CommentLexer.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentLexer.cpp?rev=181458&r1=181457&r2=181458&view=diff >> ============================================================================== >> --- cfe/trunk/lib/AST/CommentLexer.cpp (original) >> +++ cfe/trunk/lib/AST/CommentLexer.cpp Wed May 8 14:21:00 2013 >> @@ -265,6 +265,7 @@ const char *findCCommentEnd(const char * >> } >> llvm_unreachable("buffer end hit before '*/' was seen"); >> } >> + >> } // unnamed namespace >> >> void Lexer::lexCommentText(Token &T) { >> @@ -354,8 +355,17 @@ void Lexer::lexCommentText(Token &T) { >> if (!Info) { >> formTokenWithChars(T, TokenPtr, tok::unknown_command); >> T.setUnknownCommandName(CommandName); >> - Diag(T.getLocation(), diag::warn_unknown_comment_command_name); >> - return; >> + if (Info = Traits.getTypoCorrectCommandInfo(CommandName)) { >> + StringRef CorrectedName = Info->Name; >> + SourceRange CommandRange(T.getLocation().getLocWithOffset(1), >> + T.getEndLocation()); >> + Diag(T.getLocation(), diag::warn_correct_comment_command_name) >> + << CommandName << CorrectedName >> + << FixItHint::CreateReplacement(CommandRange, CorrectedName); > > We recover by assuming that the user wanted this correction. What if > they did not?.. That's the way Fix-Its are meant to work: we suggest something when we have a high level of confidence in it, and continue on as if the user had typed what we suggested. > (But I can only imagine such situation only for > external users who use comment parsing for something non-Doxygen.) This is what -fcomment-block-comments=<blah> is for, right? - Doug
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
