CommentCommandTraits.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //===--- CommentCommandTraits.cpp - Comment command properties --*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "clang/AST/CommentCommandTraits.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. namespace clang {
  12. namespace comments {
  13. #include "clang/AST/CommentCommandInfo.inc"
  14. CommandTraits::CommandTraits(llvm::BumpPtrAllocator &Allocator,
  15. const CommentOptions &CommentOptions) :
  16. NextID(llvm::array_lengthof(Commands)), Allocator(Allocator) {
  17. registerCommentOptions(CommentOptions);
  18. }
  19. void CommandTraits::registerCommentOptions(
  20. const CommentOptions &CommentOptions) {
  21. for (CommentOptions::BlockCommandNamesTy::const_iterator
  22. I = CommentOptions.BlockCommandNames.begin(),
  23. E = CommentOptions.BlockCommandNames.end();
  24. I != E; I++) {
  25. registerBlockCommand(*I);
  26. }
  27. }
  28. const CommandInfo *CommandTraits::getCommandInfoOrNULL(StringRef Name) const {
  29. if (const CommandInfo *Info = getBuiltinCommandInfo(Name))
  30. return Info;
  31. return getRegisteredCommandInfo(Name);
  32. }
  33. const CommandInfo *CommandTraits::getCommandInfo(unsigned CommandID) const {
  34. if (const CommandInfo *Info = getBuiltinCommandInfo(CommandID))
  35. return Info;
  36. return getRegisteredCommandInfo(CommandID);
  37. }
  38. const CommandInfo *
  39. CommandTraits::getTypoCorrectCommandInfo(StringRef Typo) const {
  40. const unsigned MaxEditDistance = 1;
  41. unsigned BestEditDistance = MaxEditDistance + 1;
  42. SmallVector<const CommandInfo *, 2> BestCommand;
  43. int NumOfCommands = sizeof(Commands) / sizeof(CommandInfo);
  44. for (int i = 0; i < NumOfCommands; i++) {
  45. StringRef Name = Commands[i].Name;
  46. unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
  47. if (MinPossibleEditDistance > 0 &&
  48. Typo.size() / MinPossibleEditDistance < 1)
  49. continue;
  50. unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance);
  51. if (EditDistance > MaxEditDistance)
  52. continue;
  53. if (EditDistance == BestEditDistance)
  54. BestCommand.push_back(&Commands[i]);
  55. else if (EditDistance < BestEditDistance) {
  56. BestCommand.clear();
  57. BestCommand.push_back(&Commands[i]);
  58. BestEditDistance = EditDistance;
  59. }
  60. }
  61. return (BestCommand.size() != 1) ? NULL : BestCommand[0];
  62. }
  63. CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
  64. char *Name = Allocator.Allocate<char>(CommandName.size() + 1);
  65. memcpy(Name, CommandName.data(), CommandName.size());
  66. Name[CommandName.size()] = '\0';
  67. // Value-initialize (=zero-initialize in this case) a new CommandInfo.
  68. CommandInfo *Info = new (Allocator) CommandInfo();
  69. Info->Name = Name;
  70. Info->ID = NextID++;
  71. RegisteredCommands.push_back(Info);
  72. return Info;
  73. }
  74. const CommandInfo *CommandTraits::registerUnknownCommand(
  75. StringRef CommandName) {
  76. CommandInfo *Info = createCommandInfoWithName(CommandName);
  77. Info->IsUnknownCommand = true;
  78. return Info;
  79. }
  80. const CommandInfo *CommandTraits::registerBlockCommand(StringRef CommandName) {
  81. CommandInfo *Info = createCommandInfoWithName(CommandName);
  82. Info->IsBlockCommand = true;
  83. return Info;
  84. }
  85. const CommandInfo *CommandTraits::getBuiltinCommandInfo(
  86. unsigned CommandID) {
  87. if (CommandID < llvm::array_lengthof(Commands))
  88. return &Commands[CommandID];
  89. return NULL;
  90. }
  91. const CommandInfo *CommandTraits::getRegisteredCommandInfo(
  92. StringRef Name) const {
  93. for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i) {
  94. if (RegisteredCommands[i]->Name == Name)
  95. return RegisteredCommands[i];
  96. }
  97. return NULL;
  98. }
  99. const CommandInfo *CommandTraits::getRegisteredCommandInfo(
  100. unsigned CommandID) const {
  101. return RegisteredCommands[CommandID - llvm::array_lengthof(Commands)];
  102. }
  103. } // end namespace comments
  104. } // end namespace clang