Skip to content

Commit 692ce0d

Browse files
author
Harlan Haskins
committed
Feedback and handle more cases (with added tests)
1 parent e866742 commit 692ce0d

File tree

2 files changed

+57
-14
lines changed

2 files changed

+57
-14
lines changed

lib/AST/InlinableText.cpp

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ struct ExtractInactiveRanges : public ASTWalker {
189189
};
190190
} // end anonymous namespace
191191

192+
/// Appends the textual contents of the provided source range, stripping
193+
/// the contents of comments that appear in the source.
194+
///
195+
/// Given that comments are treated as whitespace, this also appends a
196+
/// space or newline (depending if the comment was multi-line and itself
197+
/// had newlines in the body) in place of the comment, to avoid fusing tokens
198+
/// together.
192199
static void appendRange(
193200
SourceManager &sourceMgr, SourceLoc start, SourceLoc end,
194201
SmallVectorImpl<char> &scratch) {
@@ -210,28 +217,44 @@ static void appendRange(
210217
lexer.lex(token);
211218

212219
if (token.is(tok::comment)) {
213-
// Append the range from the last non-comment token to the beginning of this comment
214-
// token.
220+
// Grab the start of the full comment token (with leading trivia as well)
215221
SourceLoc commentLoc = token.getLoc();
216-
auto charRange = CharSourceRange(sourceMgr, nonCommentStart, commentLoc);
217-
StringRef text = sourceMgr.extractText(charRange);
218-
scratch.append(text.begin(), text.end());
219222

220-
// Append a single whitespace character, to avoid fusing tokens.
221-
scratch.push_back(' ');
222-
223-
// Set the start of the next non-comment range to the end of this token.
223+
// Find the end of the token (with trailing trivia)
224224
SourceLoc endLoc = Lexer::getLocForEndOfToken(sourceMgr, token.getLoc());
225225

226-
// The comment token's end location includes trailing whitespace, so trim trailing
226+
// The comment token's range includes leading/trailing whitespace, so trim
227227
// whitespace and only strip the portions of the comment that are not whitespace.
228228
CharSourceRange range = CharSourceRange(sourceMgr, commentLoc, endLoc);
229-
StringRef commentText = sourceMgr.extractText(range);
230-
unsigned whitespaceOffset = commentText.size() - commentText.rtrim().size();
231-
if (whitespaceOffset > 0) {
232-
endLoc = endLoc.getAdvancedLoc(-whitespaceOffset);
229+
StringRef fullTokenText = sourceMgr.extractText(range);
230+
unsigned leadingWhitespace = fullTokenText.size() - fullTokenText.ltrim().size();
231+
if (leadingWhitespace > 0) {
232+
commentLoc = commentLoc.getAdvancedLoc(leadingWhitespace);
233+
}
234+
235+
unsigned trailingWhitespace = fullTokenText.size() - fullTokenText.rtrim().size();
236+
if (trailingWhitespace > 0) {
237+
endLoc = endLoc.getAdvancedLoc(-trailingWhitespace);
233238
}
234239

240+
// First, extract the text up to the start of the comment, including the whitespace.
241+
auto charRange = CharSourceRange(sourceMgr, nonCommentStart, commentLoc);
242+
StringRef text = sourceMgr.extractText(charRange);
243+
scratch.append(text.begin(), text.end());
244+
245+
// Next, search through the comment text to see if it's a block comment with a newline. If so
246+
// we need to re-insert a newline to avoid fusing multi-line tokens together.
247+
auto commentTextRange = CharSourceRange(sourceMgr, commentLoc, endLoc);
248+
StringRef commentText = sourceMgr.extractText(commentTextRange);
249+
bool hasNewline = commentText.find_first_of("\n\r") != StringRef::npos;
250+
251+
// Use a newline as a filler character if the comment itself had a newline in it.
252+
char filler = hasNewline ? '\n' : ' ';
253+
254+
// Append a single whitespace filler character, to avoid fusing tokens.
255+
scratch.push_back(filler);
256+
257+
// Start the next region after the contents of the comment.
235258
nonCommentStart = endLoc;
236259
}
237260
}

test/ModuleInterface/if-configs.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,23 @@ public func hasIfCompilerCheck(_ x: () -> Bool = {
128128
}
129129

130130
// CHECK: func hasComments
131+
// CHECK-NOT: #if NOT_PROVIDED
131132
// CHECK: print(
133+
// CHECK: "this should show up"
132134
// CHECK-NOT: comment! don't mess up indentation!
133135
// CHECK: {{^}} """
134136
// CHECK: {{^}} """
137+
// CHECK: #if compiler(>=5.3) {{$}}
138+
// CHECK: print( "")
139+
// CHECK: #endif
140+
// CHECK: let x = 1
141+
// CHECK-NEXT: let y = 2
142+
// CHECK: let a = 3
143+
// CHECK: let b = 2
135144
// CHECK-NOT: #if
136145
// CHECK-NOT: comment!
137146
// CHECK: return true
147+
@inlinable
138148
public func hasComments() -> Bool {
139149
/* comment! */ // comment!
140150
#if NOT_PROVIDED
@@ -151,6 +161,16 @@ public func hasComments() -> Bool {
151161
"""
152162
""")
153163

164+
#if compiler(>=5.3) // comment!
165+
print(/*comment!*/"")
166+
#endif
167+
168+
let x = 1/*
169+
*/let y = 2
170+
171+
let a = 3
172+
/* test */let b = 2
173+
154174
#if !NOT_PROVIDED
155175
// comment!
156176
return/* comment! */true/* comment! */

0 commit comments

Comments
 (0)