Skip to content

Commit 48e48f2

Browse files
author
Harlan Haskins
authored
Merge pull request swiftlang#22302 from harlanhaskins/strings-and-things
[ParseableInterfaces] Re-escape multi-line strings in attribute messages
2 parents 4ee879e + 7834028 commit 48e48f2

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ class ASTPrinter {
207207
return *this;
208208
}
209209

210+
void printEscapedStringLiteral(StringRef str);
211+
210212
void printName(Identifier Name,
211213
PrintNameContext Context = PrintNameContext::Normal);
212214

lib/AST/ASTPrinter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,22 @@ void ASTPrinter::printTextImpl(StringRef Text) {
270270
printText(Text);
271271
}
272272

273+
void ASTPrinter::printEscapedStringLiteral(StringRef str) {
274+
SmallString<128> encodeBuf;
275+
StringRef escaped =
276+
Lexer::getEncodedStringSegment(str, encodeBuf,
277+
/*isFirstSegment*/true,
278+
/*isLastSegment*/true,
279+
/*indentToStrip*/~0U /* sentinel */);
280+
281+
// FIXME: This is wasteful, but ASTPrinter is an abstract class that doesn't
282+
// have a directly-accessible ostream.
283+
SmallString<128> escapeBuf;
284+
llvm::raw_svector_ostream os(escapeBuf);
285+
os << QuotedString(escaped);
286+
printTextImpl(escapeBuf.str());
287+
}
288+
273289
void ASTPrinter::printTypeRef(Type T, const TypeDecl *RefTo, Identifier Name) {
274290
PrintNameContext Context = PrintNameContext::Normal;
275291
if (isa<GenericTypeParamDecl>(RefTo)) {

lib/AST/Attr.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,10 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
460460
// If there's no message, but this is specifically an imported
461461
// "unavailable in Swift" attribute, synthesize a message to look good in
462462
// the generated interface.
463-
if (!Attr->Message.empty())
464-
Printer << ", message: \"" << Attr->Message << "\"";
463+
if (!Attr->Message.empty()) {
464+
Printer << ", message: ";
465+
Printer.printEscapedStringLiteral(Attr->Message);
466+
}
465467
else if (Attr->getPlatformAgnosticAvailability()
466468
== PlatformAgnosticAvailabilityKind::UnavailableInSwift)
467469
Printer << ", message: \"Not available in Swift\"";
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend -typecheck -module-name Test -emit-parseable-module-interface-path %t/Test.swiftinterface %s
4+
// RUN: %FileCheck %s < %t/Test.swiftinterface
5+
// RUN: %target-swift-frontend -build-module-from-parseable-interface %t/Test.swiftinterface -o %t/Test.swiftmodule
6+
// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules -emit-parseable-module-interface-path - %t/Test.swiftmodule -module-name Test | %FileCheck %s
7+
8+
// CHECK: @available(*, unavailable, message: "First line.\nAnother line!")
9+
// CHECK: public func catastrophicFunction()
10+
@available(*,
11+
unavailable,
12+
message: """
13+
First line.
14+
Another line!
15+
""")
16+
public func catastrophicFunction() {}
17+
18+
// CHECK: @available(*, unavailable, message: "\n First line.\n Another line!")
19+
// CHECK: public func catastrophicFunction2()
20+
@available(*, unavailable, message: "\n First line.\n Another line!")
21+
public func catastrophicFunction2() {}

0 commit comments

Comments
 (0)