clang  3.7.0
CommentCommandTraits.cpp
Go to the documentation of this file.
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 
11 #include "llvm/ADT/STLExtras.h"
12 
13 namespace clang {
14 namespace comments {
15 
16 #include "clang/AST/CommentCommandInfo.inc"
17 
18 CommandTraits::CommandTraits(llvm::BumpPtrAllocator &Allocator,
20  NextID(llvm::array_lengthof(Commands)), Allocator(Allocator) {
21  registerCommentOptions(CommentOptions);
22 }
23 
26  for (CommentOptions::BlockCommandNamesTy::const_iterator
27  I = CommentOptions.BlockCommandNames.begin(),
28  E = CommentOptions.BlockCommandNames.end();
29  I != E; I++) {
31  }
32 }
33 
34 const CommandInfo *CommandTraits::getCommandInfoOrNULL(StringRef Name) const {
35  if (const CommandInfo *Info = getBuiltinCommandInfo(Name))
36  return Info;
37  return getRegisteredCommandInfo(Name);
38 }
39 
40 const CommandInfo *CommandTraits::getCommandInfo(unsigned CommandID) const {
41  if (const CommandInfo *Info = getBuiltinCommandInfo(CommandID))
42  return Info;
43  return getRegisteredCommandInfo(CommandID);
44 }
45 
46 const CommandInfo *
48  // Single-character command impostures, such as \t or \n, should not go
49  // through the fixit logic.
50  if (Typo.size() <= 1)
51  return nullptr;
52 
53  // The maximum edit distance we're prepared to accept.
54  const unsigned MaxEditDistance = 1;
55 
58 
59  auto ConsiderCorrection = [&](const CommandInfo *Command) {
60  StringRef Name = Command->Name;
61 
62  unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
63  if (MinPossibleEditDistance <= BestEditDistance) {
64  unsigned EditDistance = Typo.edit_distance(Name, true, BestEditDistance);
65  if (EditDistance < BestEditDistance) {
66  BestEditDistance = EditDistance;
67  BestCommand.clear();
68  }
69  if (EditDistance == BestEditDistance)
70  BestCommand.push_back(Command);
71  }
72  };
73 
74  for (const auto &Command : Commands)
75  ConsiderCorrection(&Command);
76 
77  for (const auto *Command : RegisteredCommands)
78  if (!Command->IsUnknownCommand)
79  ConsiderCorrection(Command);
80 
81  return BestCommand.size() == 1 ? BestCommand[0] : nullptr;
82 }
83 
84 CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
85  char *Name = Allocator.Allocate<char>(CommandName.size() + 1);
86  memcpy(Name, CommandName.data(), CommandName.size());
87  Name[CommandName.size()] = '\0';
88 
89  // Value-initialize (=zero-initialize in this case) a new CommandInfo.
90  CommandInfo *Info = new (Allocator) CommandInfo();
91  Info->Name = Name;
92  // We only have a limited number of bits to encode command IDs in the
93  // CommandInfo structure, so the ID numbers can potentially wrap around.
94  assert((NextID < (1 << CommandInfo::NumCommandIDBits))
95  && "Too many commands. We have limited bits for the command ID.");
96  Info->ID = NextID++;
97 
98  RegisteredCommands.push_back(Info);
99 
100  return Info;
101 }
102 
104  StringRef CommandName) {
105  CommandInfo *Info = createCommandInfoWithName(CommandName);
106  Info->IsUnknownCommand = true;
107  return Info;
108 }
109 
110 const CommandInfo *CommandTraits::registerBlockCommand(StringRef CommandName) {
111  CommandInfo *Info = createCommandInfoWithName(CommandName);
112  Info->IsBlockCommand = true;
113  return Info;
114 }
115 
117  unsigned CommandID) {
118  if (CommandID < llvm::array_lengthof(Commands))
119  return &Commands[CommandID];
120  return nullptr;
121 }
122 
123 const CommandInfo *CommandTraits::getRegisteredCommandInfo(
124  StringRef Name) const {
125  for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i) {
126  if (RegisteredCommands[i]->Name == Name)
127  return RegisteredCommands[i];
128  }
129  return nullptr;
130 }
131 
132 const CommandInfo *CommandTraits::getRegisteredCommandInfo(
133  unsigned CommandID) const {
134  return RegisteredCommands[CommandID - llvm::array_lengthof(Commands)];
135 }
136 
137 } // end namespace comments
138 } // end namespace clang
139 
const unsigned MaxEditDistance
Options for controlling comment parsing.
BlockCommandNamesTy BlockCommandNames
Command names to treat as block commands in comments. Should not include the leading backslash...
Information about a single command.
const CommandInfo * getCommandInfo(StringRef Name) const
unsigned ID
The ID of the command.
llvm::SpecificBumpPtrAllocator< FormatToken > Allocator
Definition: Format.cpp:1211
const CommandInfo * getCommandInfoOrNULL(StringRef Name) const
const CommandInfo * getTypoCorrectCommandInfo(StringRef Typo) const
const CommandInfo * registerBlockCommand(StringRef CommandName)
unsigned BestEditDistance
void registerCommentOptions(const CommentOptions &CommentOptions)
StringRef Typo
static const CommandInfo * getBuiltinCommandInfo(StringRef Name)
unsigned IsUnknownCommand
True if this command is unknown. This CommandInfo object was created during parsing.
unsigned IsBlockCommand
True if this command is a block command (of any kind).
const CommandInfo * registerUnknownCommand(StringRef CommandName)
CommandTraits(llvm::BumpPtrAllocator &Allocator, const CommentOptions &CommentOptions)