-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Insert headers in global module fragment #151624
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 4 commits
f7e79ed
973ace6
e044938
dc275e9
908392a
e56d504
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 |
|---|---|---|
|
|
@@ -74,13 +74,22 @@ void skipComments(Lexer &Lex, Token &Tok) { | |
| return; | ||
| } | ||
|
|
||
| // Returns the offset after header guard directives and any comments | ||
| // before/after header guards (e.g. #ifndef/#define pair, #pragma once). If no | ||
| // header guard is present in the code, this will return the offset after | ||
| // skipping all comments from the start of the code. | ||
| unsigned getOffsetAfterHeaderGuardsAndComments(StringRef FileName, | ||
| StringRef Code, | ||
| const IncludeStyle &Style) { | ||
| bool checkAndConsumeModuleDecl(const SourceManager &SM, Lexer &Lex, | ||
| Token &Tok) { | ||
| bool Matched = Tok.is(tok::raw_identifier) && | ||
| Tok.getRawIdentifier() == "module" && | ||
| !Lex.LexFromRawLexer(Tok) && Tok.is(tok::semi) && | ||
| !Lex.LexFromRawLexer(Tok); | ||
| return Matched; | ||
| } | ||
|
|
||
| // Determines the minimum offset into the file where we want to insert header | ||
| // includes. This will be put (when available): | ||
| // - after `#pragma once` | ||
| // - after header guards (`#ifdef` and `#define`) | ||
| // - after opening global module (`module;`) | ||
| unsigned getMinHeaderInsertionOffset(StringRef FileName, StringRef Code, | ||
| const IncludeStyle &Style) { | ||
| // \p Consume returns location after header guard or 0 if no header guard is | ||
| // found. | ||
| auto ConsumeHeaderGuardAndComment = | ||
|
|
@@ -95,7 +104,17 @@ unsigned getOffsetAfterHeaderGuardsAndComments(StringRef FileName, | |
| return std::max(InitialOffset, Consume(SM, Lex, Tok)); | ||
| }); | ||
| }; | ||
| return std::max( | ||
|
|
||
| auto ModuleDecl = ConsumeHeaderGuardAndComment( | ||
| [](const SourceManager &SM, Lexer &Lex, Token Tok) -> unsigned { | ||
| if (checkAndConsumeModuleDecl(SM, Lex, Tok)) { | ||
| skipComments(Lex, Tok); | ||
| return SM.getFileOffset(Tok.getLocation()); | ||
| } | ||
| return 0; | ||
| }); | ||
|
|
||
| auto HeaderAndPPOffset = std::max( | ||
| // #ifndef/#define | ||
| ConsumeHeaderGuardAndComment( | ||
| [](const SourceManager &SM, Lexer &Lex, Token Tok) -> unsigned { | ||
|
|
@@ -115,6 +134,7 @@ unsigned getOffsetAfterHeaderGuardsAndComments(StringRef FileName, | |
| return SM.getFileOffset(Tok.getLocation()); | ||
| return 0; | ||
| })); | ||
| return std::max(HeaderAndPPOffset, ModuleDecl); | ||
|
Collaborator
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. Technically, this function is no longer doing what its name says, Can we rename it to
Contributor
Author
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. Thanks, done! Does the comment look okay? 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. If rather say something like: Feel free to rephrase or ignore
Contributor
Author
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. This does read better, yeah. Will push after current CI run to prevent a restart. Edit: done |
||
| } | ||
|
|
||
| // Check if a sequence of tokens is like | ||
|
|
@@ -280,8 +300,7 @@ const llvm::Regex HeaderIncludes::IncludeRegex(IncludeRegexPattern); | |
| HeaderIncludes::HeaderIncludes(StringRef FileName, StringRef Code, | ||
| const IncludeStyle &Style) | ||
| : FileName(FileName), Code(Code), FirstIncludeOffset(-1), | ||
| MinInsertOffset( | ||
| getOffsetAfterHeaderGuardsAndComments(FileName, Code, Style)), | ||
| MinInsertOffset(getMinHeaderInsertionOffset(FileName, Code, Style)), | ||
| MaxInsertOffset(MinInsertOffset + | ||
| getMaxHeaderInsertionOffset( | ||
| FileName, Code.drop_front(MinInsertOffset), Style)), | ||
|
|
||
|
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 like the test cases you wrote. I do think we should add at least one extra where we already had some includes in the source code. Such that we know this works in such case as well. (I don't expect failure based on your code)
Contributor
Author
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. Thanks for the explanation here! Should I combine all into the same test case, or are 3 separate ones okay? I just realized the other tests seem to combine multiple checks into one gtest test. Edit: Ah, it seems I was mistaken, kept them as 3 separate tests. Let me know if the naming looks okay! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add "after any comments at the start of the file or immediately following one of the above constructs"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done