clang 20.0.0git
CommentCommandTraits.cpp
Go to the documentation of this file.
1//===--- CommentCommandTraits.cpp - Comment command properties --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include <cassert>
11
12namespace clang {
13namespace comments {
14
15#include "clang/AST/CommentCommandInfo.inc"
16
17CommandTraits::CommandTraits(llvm::BumpPtrAllocator &Allocator,
19 : NextID(std::size(Commands)), Allocator(Allocator) {
21}
22
25 for (CommentOptions::BlockCommandNamesTy::const_iterator
28 I != E; I++) {
30 }
31}
32
34 if (const CommandInfo *Info = getBuiltinCommandInfo(Name))
35 return Info;
36 return getRegisteredCommandInfo(Name);
37}
38
39const CommandInfo *CommandTraits::getCommandInfo(unsigned CommandID) const {
40 if (const CommandInfo *Info = getBuiltinCommandInfo(CommandID))
41 return Info;
42 return getRegisteredCommandInfo(CommandID);
43}
44
45const CommandInfo *
47 // Single-character command impostures, such as \t or \n, should not go
48 // through the fixit logic.
49 if (Typo.size() <= 1)
50 return nullptr;
51
52 // The maximum edit distance we're prepared to accept.
53 const unsigned MaxEditDistance = 1;
54
55 unsigned BestEditDistance = MaxEditDistance;
57
58 auto ConsiderCorrection = [&](const CommandInfo *Command) {
59 StringRef Name = Command->Name;
60
61 unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
62 if (MinPossibleEditDistance <= BestEditDistance) {
63 unsigned EditDistance = Typo.edit_distance(Name, true, BestEditDistance);
64 if (EditDistance < BestEditDistance) {
65 BestEditDistance = EditDistance;
66 BestCommand.clear();
67 }
68 if (EditDistance == BestEditDistance)
69 BestCommand.push_back(Command);
70 }
71 };
72
73 for (const auto &Command : Commands)
74 ConsiderCorrection(&Command);
75
76 for (const auto *Command : RegisteredCommands)
77 if (!Command->IsUnknownCommand)
78 ConsiderCorrection(Command);
79
80 return BestCommand.size() == 1 ? BestCommand[0] : nullptr;
81}
82
83CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
84 char *Name = Allocator.Allocate<char>(CommandName.size() + 1);
85 memcpy(Name, CommandName.data(), CommandName.size());
86 Name[CommandName.size()] = '\0';
87
88 // Value-initialize (=zero-initialize in this case) a new CommandInfo.
89 CommandInfo *Info = new (Allocator) CommandInfo();
90 Info->Name = Name;
91 // We only have a limited number of bits to encode command IDs in the
92 // CommandInfo structure, so the ID numbers can potentially wrap around.
93 assert((NextID < (1 << CommandInfo::NumCommandIDBits))
94 && "Too many commands. We have limited bits for the command ID.");
95 Info->ID = NextID++;
96
97 RegisteredCommands.push_back(Info);
98
99 return Info;
100}
101
103 StringRef CommandName) {
104 CommandInfo *Info = createCommandInfoWithName(CommandName);
105 Info->IsUnknownCommand = true;
106 return Info;
107}
108
110 CommandInfo *Info = createCommandInfoWithName(CommandName);
111 Info->IsBlockCommand = true;
112 return Info;
113}
114
116 unsigned CommandID) {
117 if (CommandID < std::size(Commands))
118 return &Commands[CommandID];
119 return nullptr;
120}
121
122const CommandInfo *CommandTraits::getRegisteredCommandInfo(
123 StringRef Name) const {
124 for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i) {
125 if (RegisteredCommands[i]->Name == Name)
126 return RegisteredCommands[i];
127 }
128 return nullptr;
129}
130
131const CommandInfo *CommandTraits::getRegisteredCommandInfo(
132 unsigned CommandID) const {
133 return RegisteredCommands[CommandID - std::size(Commands)];
134}
135
136} // end namespace comments
137} // end namespace clang
138
Expr * E
__DEVICE__ long long abs(long long __n)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
static const CommandInfo * getBuiltinCommandInfo(StringRef Name)
const CommandInfo * getCommandInfo(StringRef Name) const
CommandTraits(llvm::BumpPtrAllocator &Allocator, const CommentOptions &CommentOptions)
const CommandInfo * registerBlockCommand(StringRef CommandName)
const CommandInfo * registerUnknownCommand(StringRef CommandName)
void registerCommentOptions(const CommentOptions &CommentOptions)
const CommandInfo * getCommandInfoOrNULL(StringRef Name) const
const CommandInfo * getTypoCorrectCommandInfo(StringRef Typo) const
The JSON file list parser is used to communicate input to InstallAPI.
Options for controlling comment parsing.
BlockCommandNamesTy BlockCommandNames
Command names to treat as block commands in comments.
Information about a single command.
unsigned IsBlockCommand
True if this command is a block command (of any kind).
unsigned ID
The ID of the command.
unsigned IsUnknownCommand
True if this command is unknown.