Skip to content

[Parsing] NFC: metaprogram contextual decl keywords into Attr.def #15818

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 70 additions & 33 deletions include/swift/AST/Attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,30 @@
#define DECL_ATTR(SPELLING, CLASS, OPTIONS, CODE)
#endif

#ifndef CONTEXTUAL_DECL_ATTR
#define CONTEXTUAL_DECL_ATTR(SPELLING, CLASS, OPTIONS, CODE) \
DECL_ATTR(SPELLING, CLASS, OPTIONS, CODE)
#endif

#ifndef SIMPLE_DECL_ATTR
#define SIMPLE_DECL_ATTR(X, CLASS, OPTIONS, CODE) DECL_ATTR(X, CLASS, OPTIONS, CODE)
#define SIMPLE_DECL_ATTR(X, CLASS, OPTIONS, CODE) \
DECL_ATTR(X, CLASS, OPTIONS, CODE)
#endif

#ifndef CONTEXTUAL_SIMPLE_DECL_ATTR
#define CONTEXTUAL_SIMPLE_DECL_ATTR(X, CLASS, OPTIONS, CODE) \
SIMPLE_DECL_ATTR(X, CLASS, OPTIONS, CODE)
#endif

#ifndef DECL_ATTR_ALIAS
#define DECL_ATTR_ALIAS(SPELLING, CLASS)
#endif

#ifndef CONTEXTUAL_DECL_ATTR_ALIAS
#define CONTEXTUAL_DECL_ATTR_ALIAS(SPELLING, CLASS) \
DECL_ATTR_ALIAS(SPELLING, CLASS)
#endif

#ifndef TYPE_ATTR
#define TYPE_ATTR(X)
#endif
Expand Down Expand Up @@ -92,18 +108,21 @@ DECL_ATTR(available, Available,
OnConstructor | OnDestructor | OnTypeAlias | OnSubscript |
OnEnumElement | OnExtension | AllowMultipleAttributes | LongAttribute, 1)

SIMPLE_DECL_ATTR(final, Final,
OnClass | OnFunc | OnVar | OnSubscript|DeclModifier, 2)
CONTEXTUAL_SIMPLE_DECL_ATTR(final, Final, DeclModifier |
OnClass | OnFunc | OnVar | OnSubscript,
2)

DECL_ATTR(objc, ObjC,
OnFunc | OnClass | OnProtocol | OnExtension | OnVar | OnSubscript |
OnConstructor | OnDestructor | OnEnum | OnEnumElement, 3)

SIMPLE_DECL_ATTR(required, Required,
OnConstructor|DeclModifier, 4)
CONTEXTUAL_SIMPLE_DECL_ATTR(required, Required, DeclModifier |
OnConstructor,
4)

SIMPLE_DECL_ATTR(optional, Optional,
OnConstructor|OnFunc|OnVar|OnSubscript|DeclModifier, 5)
CONTEXTUAL_SIMPLE_DECL_ATTR(optional, Optional, DeclModifier |
OnConstructor | OnFunc | OnVar | OnSubscript,
5)

/// NOTE: 6 is unused

Expand Down Expand Up @@ -131,7 +150,9 @@ SIMPLE_DECL_ATTR(IBOutlet, IBOutlet,

SIMPLE_DECL_ATTR(NSManaged, NSManaged, OnVar | OnFunc, 15)

SIMPLE_DECL_ATTR(lazy, Lazy, OnVar|DeclModifier, 16)
CONTEXTUAL_SIMPLE_DECL_ATTR(lazy, Lazy, DeclModifier |
OnVar,
16)

SIMPLE_DECL_ATTR(LLDBDebuggerFunction, LLDBDebuggerFunction, OnFunc |
UserInaccessible, 17)
Expand All @@ -148,12 +169,21 @@ DECL_ATTR(_semantics, Semantics,
OnFunc | OnConstructor | OnDestructor | OnSubscript |
AllowMultipleAttributes | UserInaccessible, 21)

SIMPLE_DECL_ATTR(dynamic, Dynamic,
OnFunc | OnVar | OnSubscript | OnConstructor | DeclModifier, 22)
CONTEXTUAL_SIMPLE_DECL_ATTR(dynamic, Dynamic, DeclModifier |
OnFunc | OnVar | OnSubscript | OnConstructor,
22)

SIMPLE_DECL_ATTR(infix , Infix , OnFunc | OnOperator | DeclModifier, 23)
SIMPLE_DECL_ATTR(prefix , Prefix , OnFunc | OnOperator | DeclModifier, 24)
SIMPLE_DECL_ATTR(postfix, Postfix, OnFunc | OnOperator | DeclModifier, 25)
CONTEXTUAL_SIMPLE_DECL_ATTR(infix, Infix, DeclModifier |
OnFunc | OnOperator,
23)

CONTEXTUAL_SIMPLE_DECL_ATTR(prefix, Prefix, DeclModifier |
OnFunc | OnOperator,
24)

CONTEXTUAL_SIMPLE_DECL_ATTR(postfix, Postfix, DeclModifier |
OnFunc | OnOperator,
25)

SIMPLE_DECL_ATTR(_transparent, Transparent,
OnFunc|OnConstructor|OnVar|UserInaccessible, 26)
Expand All @@ -176,22 +206,24 @@ DECL_ATTR(_specialize, Specialize,

SIMPLE_DECL_ATTR(objcMembers, ObjCMembers, OnClass, 34)

// Non-serialized attributes.
CONTEXTUAL_SIMPLE_DECL_ATTR(__consuming, Consuming, DeclModifier |
OnFunc |
NotSerialized, 40)

CONTEXTUAL_SIMPLE_DECL_ATTR(mutating, Mutating, DeclModifier |
OnFunc |
NotSerialized, 41)

SIMPLE_DECL_ATTR(__consuming, Consuming, OnFunc | DeclModifier | NotSerialized,
/* Not serialized */ 40)
SIMPLE_DECL_ATTR(mutating, Mutating, OnFunc | DeclModifier | NotSerialized,
/* Not serialized */ 41)
SIMPLE_DECL_ATTR(nonmutating, NonMutating, OnFunc | DeclModifier | NotSerialized,
/* Not serialized */ 42)
CONTEXTUAL_SIMPLE_DECL_ATTR(nonmutating, NonMutating, DeclModifier |
OnFunc |
NotSerialized, 42)

SIMPLE_DECL_ATTR(convenience, Convenience,
OnConstructor|DeclModifier|NotSerialized, 43)
CONTEXTUAL_SIMPLE_DECL_ATTR(convenience, Convenience,
OnConstructor | DeclModifier | NotSerialized, 43)

SIMPLE_DECL_ATTR(override, Override,
OnFunc | OnVar | OnSubscript | OnConstructor | DeclModifier |
NotSerialized,
/* Not serialized */44)
CONTEXTUAL_SIMPLE_DECL_ATTR(override, Override, DeclModifier |
OnFunc | OnVar | OnSubscript | OnConstructor |
NotSerialized, 44)

SIMPLE_DECL_ATTR(sil_stored, SILStored, OnVar | NotSerialized | SILOnly,
/* Not serialized */45)
Expand All @@ -204,7 +236,7 @@ DECL_ATTR(private, AccessControl,
DECL_ATTR_ALIAS(fileprivate, AccessControl)
DECL_ATTR_ALIAS(internal, AccessControl)
DECL_ATTR_ALIAS(public, AccessControl)

CONTEXTUAL_DECL_ATTR_ALIAS(open, AccessControl)

DECL_ATTR(__setter_access, SetterAccess,
OnVar | OnSubscript | DeclModifier | NotSerialized | RejectByParser,
Expand All @@ -214,9 +246,11 @@ DECL_ATTR(__raw_doc_comment, RawDocComment, OnAnyDecl |
NotSerialized | RejectByParser, /* Not serialized */48)

// Also handles unowned and unowned(weak).
DECL_ATTR(weak, ReferenceOwnership, OnVar | OnParam | DeclModifier | NotSerialized,
/* Not serialized */49)
DECL_ATTR_ALIAS(unowned, ReferenceOwnership)
CONTEXTUAL_DECL_ATTR(weak, ReferenceOwnership, DeclModifier |
OnVar | OnParam |
NotSerialized, 49)

CONTEXTUAL_DECL_ATTR_ALIAS(unowned, ReferenceOwnership)

DECL_ATTR(effects, Effects, OnFunc | OnConstructor | OnDestructor |
UserInaccessible, 50)
Expand Down Expand Up @@ -246,9 +280,9 @@ SIMPLE_DECL_ATTR(rethrows, Rethrows,
DECL_ATTR(_swift_native_objc_runtime_base, SwiftNativeObjCRuntimeBase,
OnClass | UserInaccessible, 59)

SIMPLE_DECL_ATTR(indirect, Indirect,
OnEnum | OnEnumElement | DeclModifier,
60)
CONTEXTUAL_SIMPLE_DECL_ATTR(indirect, Indirect, DeclModifier |
OnEnum | OnEnumElement,
60)

SIMPLE_DECL_ATTR(warn_unqualified_access, WarnUnqualifiedAccess,
OnFunc /*| OnVar*/ | LongAttribute, 61)
Expand Down Expand Up @@ -316,5 +350,8 @@ SIMPLE_DECL_ATTR(_frozen, Frozen, OnEnum | UserInaccessible, 76)

#undef TYPE_ATTR
#undef DECL_ATTR_ALIAS
#undef CONTEXTUAL_DECL_ATTR_ALIAS
#undef SIMPLE_DECL_ATTR
#undef CONTEXTUAL_SIMPLE_DECL_ATTR
#undef DECL_ATTR
#undef CONTEXTUAL_DECL_ATTR
58 changes: 18 additions & 40 deletions include/swift/Parse/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "swift/Syntax/TokenKinds.h"
#include "swift/Config.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"

namespace swift {

Expand All @@ -38,17 +39,17 @@ class Token {
/// \brief Whether this token is the first token on the line.
unsigned AtStartOfLine : 1;

/// \brief The length of the comment that precedes the token.
///
/// Hopefully 128 Mib is enough.
unsigned CommentLength : 27;

/// \brief Whether this token is an escaped `identifier` token.
unsigned EscapedIdentifier : 1;

/// Modifiers for string literals
unsigned MultilineString : 1;

// Padding bits == 32 - sizeof(Kind) * 8 - 3;

/// \brief The length of the comment that precedes the token.
unsigned CommentLength;

/// Text - The actual string covered by the token in the source buffer.
StringRef Text;

Expand All @@ -59,15 +60,12 @@ class Token {
}

public:
Token() : Kind(tok::NUM_TOKENS), AtStartOfLine(false), CommentLength(0),
EscapedIdentifier(false) {}

Token(tok Kind, StringRef Text, unsigned CommentLength)
: Kind(Kind), AtStartOfLine(false), CommentLength(CommentLength),
EscapedIdentifier(false), MultilineString(false),
Token(tok Kind, StringRef Text, unsigned CommentLength = 0)
: Kind(Kind), AtStartOfLine(false), EscapedIdentifier(false),
MultilineString(false), CommentLength(CommentLength),
Text(Text) {}

Token(tok Kind, StringRef Text): Token(Kind, Text, 0) {};
Token() : Token(tok::NUM_TOKENS, {}, 0) {}

tok getKind() const { return Kind; }
void setKind(tok K) { Kind = K; }
Expand Down Expand Up @@ -139,34 +137,14 @@ class Token {
if (isNot(tok::identifier) || isEscapedIdentifier() || Text.empty())
return false;

switch (Text[0]) {
case 'c':
return Text == "convenience";
case 'd':
return Text == "dynamic";
case 'f':
return Text == "final";
case 'i':
return Text == "indirect" || Text == "infix";
case 'l':
return Text == "lazy";
case 'm':
return Text == "mutating";
case 'n':
return Text == "nonmutating";
case 'o':
return Text == "open" || Text == "override" || Text == "optional";
case 'p':
return Text == "prefix" || Text == "postfix";
case 'r':
return Text == "required";
case 'u':
return Text == "unowned";
case 'w':
return Text == "weak";
default:
return false;
}
return llvm::StringSwitch<bool>(Text)
#define CONTEXTUAL_CASE(KW) .Case(#KW, true)
#define CONTEXTUAL_DECL_ATTR(KW, ...) CONTEXTUAL_CASE(KW)
#define CONTEXTUAL_DECL_ATTR_ALIAS(KW, ...) CONTEXTUAL_CASE(KW)
#define CONTEXTUAL_SIMPLE_DECL_ATTR(KW, ...) CONTEXTUAL_CASE(KW)
#include "swift/AST/Attr.def"
#undef CONTEXTUAL_CASE
.Default(false);
}

bool isContextualPunctuator(StringRef ContextPunc) const {
Expand Down
22 changes: 8 additions & 14 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4852,20 +4852,14 @@ static void addDeclKeywords(CodeCompletionResultSink &Sink) {
auto AddCSKeyword = [&](StringRef Name) {
AddKeyword(Name, CodeCompletionKeywordKind::None);
};
AddCSKeyword("weak");
AddCSKeyword("unowned");
AddCSKeyword("optional");
AddCSKeyword("required");
AddCSKeyword("lazy");
AddCSKeyword("final");
AddCSKeyword("dynamic");
AddCSKeyword("prefix");
AddCSKeyword("postfix");
AddCSKeyword("infix");
AddCSKeyword("override");
AddCSKeyword("mutating");
AddCSKeyword("nonmutating");
AddCSKeyword("convenience");

#define CONTEXTUAL_CASE(KW) AddCSKeyword(#KW);
#define CONTEXTUAL_DECL_ATTR(KW, ...) CONTEXTUAL_CASE(KW)
#define CONTEXTUAL_DECL_ATTR_ALIAS(KW, ...) CONTEXTUAL_CASE(KW)
#define CONTEXTUAL_SIMPLE_DECL_ATTR(KW, ...) CONTEXTUAL_CASE(KW)
#include <swift/AST/Attr.def>
#undef CONTEXTUAL_CASE

}

static void addStmtKeywords(CodeCompletionResultSink &Sink, bool MaybeFuncBody) {
Expand Down
26 changes: 8 additions & 18 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1962,24 +1962,14 @@ bool Parser::parseDeclModifierList(DeclAttributes &Attributes,
break;

DeclAttrKind Kind = llvm::StringSwitch<DeclAttrKind>(Tok.getText())
.Case("open", DAK_AccessControl)
.Case("weak", DAK_ReferenceOwnership)
.Case("unowned", DAK_ReferenceOwnership)
.Case("optional", DAK_Optional)
.Case("required", DAK_Required)
.Case("lazy", DAK_Lazy)
.Case("final", DAK_Final)
.Case("dynamic", DAK_Dynamic)
.Case("prefix", DAK_Prefix)
.Case("postfix", DAK_Postfix)
.Case("indirect", DAK_Indirect)
.Case("infix", DAK_Infix)
.Case("override", DAK_Override)
.Case("mutating", DAK_Mutating)
.Case("nonmutating", DAK_NonMutating)
.Case("__consuming", DAK_Consuming)
.Case("convenience", DAK_Convenience)
.Default(DAK_Count);
#define CONTEXTUAL_CASE(KW, CLASS) .Case(#KW, DAK_##CLASS)
#define CONTEXTUAL_DECL_ATTR(KW, CLASS, ...) CONTEXTUAL_CASE(KW, CLASS)
#define CONTEXTUAL_DECL_ATTR_ALIAS(KW, CLASS) CONTEXTUAL_CASE(KW, CLASS)
#define CONTEXTUAL_SIMPLE_DECL_ATTR(KW, CLASS, ...) CONTEXTUAL_CASE(KW, CLASS)
#include <swift/AST/Attr.def>
#undef CONTEXTUAL_CASE
.Default(DAK_Count);

if (Kind == DAK_Count)
break;

Expand Down
27 changes: 27 additions & 0 deletions test/SourceKit/CodeComplete/complete_override.swift.response
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{
key.results: [
{
key.kind: source.lang.swift.keyword,
key.name: "__consuming",
key.sourcetext: "__consuming",
key.description: "__consuming",
key.typename: "",
key.context: source.codecompletion.context.none,
key.num_bytes_to_erase: 0
},
{
key.kind: source.lang.swift.keyword,
key.name: "associatedtype",
Expand Down Expand Up @@ -110,6 +119,15 @@
key.context: source.codecompletion.context.none,
key.num_bytes_to_erase: 0
},
{
key.kind: source.lang.swift.keyword,
key.name: "indirect",
key.sourcetext: "indirect",
key.description: "indirect",
key.typename: "",
key.context: source.codecompletion.context.none,
key.num_bytes_to_erase: 0
},
{
key.kind: source.lang.swift.keyword,
key.name: "infix",
Expand Down Expand Up @@ -193,6 +211,15 @@
key.context: source.codecompletion.context.none,
key.num_bytes_to_erase: 0
},
{
key.kind: source.lang.swift.keyword,
key.name: "open",
key.sourcetext: "open",
key.description: "open",
key.typename: "",
key.context: source.codecompletion.context.none,
key.num_bytes_to_erase: 0
},
{
key.kind: source.lang.swift.keyword,
key.name: "operator",
Expand Down