Skip to content

Commit 899d1a4

Browse files
committed
[NFC] Centralize ObjCSelector helper
1 parent e422947 commit 899d1a4

File tree

4 files changed

+45
-72
lines changed

4 files changed

+45
-72
lines changed

include/swift/AST/Identifier.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,13 @@ class ObjCSelector {
820820
/// Construct an invalid ObjCSelector.
821821
ObjCSelector() : Storage() {}
822822

823+
/// Split \p string into selector pieces on colons to create an ObjCSelector.
824+
///
825+
/// This should not be used to parse selectors written directly in Swift
826+
/// source source code (e.g. the argument of an @objc attribute). Use the
827+
/// parser for that.
828+
static llvm::Optional<ObjCSelector> parse(ASTContext &ctx, StringRef string);
829+
823830
/// Convert to true if the decl name is valid.
824831
explicit operator bool() const { return (bool)Storage; }
825832

lib/AST/AccessNotes.cpp

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,42 +24,6 @@
2424
#include "llvm/ADT/StringRef.h"
2525
#include "llvm/Support/YAMLTraits.h"
2626

27-
// FIXME: Copied from MiscDiagnostics--don't do that.
28-
static llvm::Optional<swift::ObjCSelector>
29-
parseObjCSelector(swift::ASTContext &ctx, llvm::StringRef string) {
30-
using namespace swift;
31-
32-
// Find the first colon.
33-
auto colonPos = string.find(':');
34-
35-
// If there is no colon, we have a nullary selector.
36-
if (colonPos == StringRef::npos) {
37-
if (string.empty() || !Lexer::isIdentifier(string)) return None;
38-
return ObjCSelector(ctx, 0, { ctx.getIdentifier(string) });
39-
}
40-
41-
SmallVector<Identifier, 2> pieces;
42-
do {
43-
// Check whether we have a valid selector piece.
44-
auto piece = string.substr(0, colonPos);
45-
if (piece.empty()) {
46-
pieces.push_back(Identifier());
47-
} else {
48-
if (!Lexer::isIdentifier(piece)) return None;
49-
pieces.push_back(ctx.getIdentifier(piece));
50-
}
51-
52-
// Move to the next piece.
53-
string = string.substr(colonPos+1);
54-
colonPos = string.find(':');
55-
} while (colonPos != StringRef::npos);
56-
57-
// If anything remains of the string, it's not a selector.
58-
if (!string.empty()) return None;
59-
60-
return ObjCSelector(ctx, pieces.size(), pieces);
61-
}
62-
6327
namespace swift {
6428

6529
AccessNoteDeclName::AccessNoteDeclName()
@@ -237,7 +201,7 @@ AccessNotes::load(ASTContext &ctx, llvm::MemoryBuffer *buffer) {
237201
AccessNotes notes;
238202
yamlIn >> notes;
239203

240-
if (yamlIn.error())
204+
if (errors)
241205
return llvm::Expected<AccessNotes>(std::move(errors));
242206

243207
return notes;
@@ -275,7 +239,7 @@ StringRef ScalarTraits<ObjCSelector>::input(StringRef str, void *ctxPtr,
275239
ObjCSelector &selector) {
276240
ASTContext &ctx = *static_cast<ASTContext *>(ctxPtr);
277241

278-
if (auto sel = parseObjCSelector(ctx, str)) {
242+
if (auto sel = ObjCSelector::parse(ctx, str)) {
279243
selector = *sel;
280244
return "";
281245
}

lib/AST/Identifier.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#include "swift/AST/ASTContext.h"
1718
#include "swift/AST/Identifier.h"
19+
#include "swift/Parse/Lexer.h"
1820
#include "llvm/ADT/StringExtras.h"
1921
#include "llvm/Support/raw_ostream.h"
2022
#include "llvm/Support/ConvertUTF.h"
@@ -228,6 +230,39 @@ ObjCSelector::ObjCSelector(ASTContext &ctx, unsigned numArgs,
228230
Storage = DeclName(ctx, Identifier(), pieces);
229231
}
230232

233+
llvm::Optional<ObjCSelector>
234+
ObjCSelector::parse(ASTContext &ctx, StringRef string) {
235+
// Find the first colon.
236+
auto colonPos = string.find(':');
237+
238+
// If there is no colon, we have a nullary selector.
239+
if (colonPos == StringRef::npos) {
240+
if (string.empty() || !Lexer::isIdentifier(string)) return None;
241+
return ObjCSelector(ctx, 0, { ctx.getIdentifier(string) });
242+
}
243+
244+
SmallVector<Identifier, 2> pieces;
245+
do {
246+
// Check whether we have a valid selector piece.
247+
auto piece = string.substr(0, colonPos);
248+
if (piece.empty()) {
249+
pieces.push_back(Identifier());
250+
} else {
251+
if (!Lexer::isIdentifier(piece)) return None;
252+
pieces.push_back(ctx.getIdentifier(piece));
253+
}
254+
255+
// Move to the next piece.
256+
string = string.substr(colonPos+1);
257+
colonPos = string.find(':');
258+
} while (colonPos != StringRef::npos);
259+
260+
// If anything remains of the string, it's not a selector.
261+
if (!string.empty()) return None;
262+
263+
return ObjCSelector(ctx, pieces.size(), pieces);
264+
}
265+
231266
ObjCSelectorFamily ObjCSelector::getSelectorFamily() const {
232267
StringRef text = getSelectorPieces().front().get();
233268
while (!text.empty() && text[0] == '_') text = text.substr(1);

lib/Sema/MiscDiagnostics.cpp

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3427,39 +3427,6 @@ static void checkStmtConditionTrailingClosure(ASTContext &ctx, const Stmt *S) {
34273427
}
34283428
}
34293429

3430-
static Optional<ObjCSelector>
3431-
parseObjCSelector(ASTContext &ctx, StringRef string) {
3432-
// Find the first colon.
3433-
auto colonPos = string.find(':');
3434-
3435-
// If there is no colon, we have a nullary selector.
3436-
if (colonPos == StringRef::npos) {
3437-
if (string.empty() || !Lexer::isIdentifier(string)) return None;
3438-
return ObjCSelector(ctx, 0, { ctx.getIdentifier(string) });
3439-
}
3440-
3441-
SmallVector<Identifier, 2> pieces;
3442-
do {
3443-
// Check whether we have a valid selector piece.
3444-
auto piece = string.substr(0, colonPos);
3445-
if (piece.empty()) {
3446-
pieces.push_back(Identifier());
3447-
} else {
3448-
if (!Lexer::isIdentifier(piece)) return None;
3449-
pieces.push_back(ctx.getIdentifier(piece));
3450-
}
3451-
3452-
// Move to the next piece.
3453-
string = string.substr(colonPos+1);
3454-
colonPos = string.find(':');
3455-
} while (colonPos != StringRef::npos);
3456-
3457-
// If anything remains of the string, it's not a selector.
3458-
if (!string.empty()) return None;
3459-
3460-
return ObjCSelector(ctx, pieces.size(), pieces);
3461-
}
3462-
34633430

34643431
namespace {
34653432

@@ -3627,7 +3594,7 @@ class ObjCSelectorWalker : public ASTWalker {
36273594

36283595
// Try to parse the string literal as an Objective-C selector, and complain
36293596
// if it isn't one.
3630-
auto selector = parseObjCSelector(Ctx, stringLiteral->getValue());
3597+
auto selector = ObjCSelector::parse(Ctx, stringLiteral->getValue());
36313598
if (!selector) {
36323599
auto diag = Ctx.Diags.diagnose(stringLiteral->getLoc(),
36333600
diag::selector_literal_invalid);

0 commit comments

Comments
 (0)