-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[clang-doc] fix flaky test in clang-doc #101387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3ec4d5b
114a572
556adbf
ff69b59
2539d74
9fdf07a
6d981a3
c301f1b
c26ce3c
9f88c79
92d874b
fc2a139
49b39e6
7255f85
f049be5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,6 +104,7 @@ struct Reference { | |
|
||
bool mergeable(const Reference &Other); | ||
void merge(Reference &&I); | ||
bool operator<(const Reference &Other) const { return Name < Other.Name; } | ||
|
||
/// Returns the path for this Reference relative to CurrentPath. | ||
llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const; | ||
|
@@ -145,6 +146,8 @@ struct ScopeChildren { | |
std::vector<FunctionInfo> Functions; | ||
std::vector<EnumInfo> Enums; | ||
std::vector<TypedefInfo> Typedefs; | ||
|
||
void sort(); | ||
}; | ||
|
||
// A base struct for TypeInfos | ||
|
@@ -245,6 +248,11 @@ struct Location { | |
std::tie(Other.LineNumber, Other.Filename); | ||
} | ||
|
||
bool operator!=(const Location &Other) const { | ||
return std::tie(LineNumber, Filename) != | ||
std::tie(Other.LineNumber, Other.Filename); | ||
} | ||
|
||
// This operator is used to sort a vector of Locations. | ||
// No specific order (attributes more important than others) is required. Any | ||
// sort is enough, the order is only needed to call std::unique after sorting | ||
|
@@ -270,10 +278,12 @@ struct Info { | |
|
||
virtual ~Info() = default; | ||
|
||
Info &operator=(Info &&Other) = default; | ||
|
||
SymbolID USR = | ||
SymbolID(); // Unique identifier for the decl described by this Info. | ||
const InfoType IT = InfoType::IT_default; // InfoType of this particular Info. | ||
SmallString<16> Name; // Unqualified name of the decl. | ||
InfoType IT = InfoType::IT_default; // InfoType of this particular Info. | ||
SmallString<16> Name; // Unqualified name of the decl. | ||
llvm::SmallVector<Reference, 4> | ||
Namespace; // List of parent namespaces for this decl. | ||
std::vector<CommentInfo> Description; // Comment description of this decl. | ||
|
@@ -312,6 +322,20 @@ struct SymbolInfo : public Info { | |
|
||
std::optional<Location> DefLoc; // Location where this decl is defined. | ||
llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared. | ||
|
||
bool operator<(const SymbolInfo &Other) const { | ||
// Sort by declaration location since we want the doc to be | ||
// generated in the order of the source code. | ||
Comment on lines
+327
to
+328
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentation often sorts methods by name, so its easy to find things. As an example, here's Rust's Doxygen maintains source order, so its fine to do it that way for now, but we may want to consider making that a configurable option, since I think its more user friendly to do it that way (and arguably more modern). |
||
// If the declaration location is the same, or not present | ||
// we sort by defined location otherwise fallback to the extracted name | ||
if (Loc.size() > 0 && Other.Loc.size() > 0 && Loc[0] != Other.Loc[0]) | ||
return Loc[0] < Other.Loc[0]; | ||
PeterChou1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (DefLoc && Other.DefLoc && *DefLoc != *Other.DefLoc) | ||
return *DefLoc < *Other.DefLoc; | ||
|
||
return extractName() < Other.extractName(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at the overall comparison, you could probably use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not too familiar with what you are talking about can you give an example? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
}; | ||
|
||
// TODO: Expand to allow for documenting templating and default args. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -205,6 +205,22 @@ llvm::Error getHtmlAssetFiles(const char *Argv0, | |
return getDefaultAssetFiles(Argv0, CDCtx); | ||
} | ||
|
||
/// Make the output of clang-doc deterministic by sorting the children of | ||
/// namespaces and records. | ||
void sortUsrToInfo(llvm::StringMap<std::unique_ptr<doc::Info>> &USRToInfo) { | ||
for (auto &I : USRToInfo) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No since USRToInfo is generated on a per file basis so there's no need to sort it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That doesn't necessarily rule out its own iteration order affecting the output. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How so? StringMap iteration order is not guaranteed to be deterministic and I don't think it was affecting the tests before |
||
auto &Info = I.second; | ||
if (Info->IT == doc::InfoType::IT_namespace) { | ||
auto *Namespace = static_cast<clang::doc::NamespaceInfo *>(Info.get()); | ||
Namespace->Children.sort(); | ||
} | ||
if (Info->IT == doc::InfoType::IT_record) { | ||
auto *Record = static_cast<clang::doc::RecordInfo *>(Info.get()); | ||
Record->Children.sort(); | ||
} | ||
} | ||
} | ||
|
||
int main(int argc, const char **argv) { | ||
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); | ||
std::error_code OK; | ||
|
@@ -341,6 +357,8 @@ Example usage for a project using a compile commands database: | |
if (Error) | ||
return 1; | ||
|
||
sortUsrToInfo(USRToInfo); | ||
|
||
// Ensure the root output directory exists. | ||
if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); | ||
Err != std::error_code()) { | ||
|
Uh oh!
There was an error while loading. Please reload this page.