Skip to content

Commit 1a7bb8c

Browse files
committed
Merge Attribute and CustomAttribute
1 parent 5b83f5e commit 1a7bb8c

File tree

27 files changed

+131
-854
lines changed

27 files changed

+131
-854
lines changed

CodeGeneration/Sources/SyntaxSupport/gyb_generated/AttributeNodes.swift

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,39 +24,6 @@ public let ATTRIBUTE_NODES: [Node] = [
2424
element: "Token",
2525
omitWhenEmpty: true),
2626

27-
Node(name: "CustomAttribute",
28-
nameForDiagnostics: "attribute",
29-
description: "A custom `@` attribute.",
30-
kind: "Syntax",
31-
children: [
32-
Child(name: "AtSignToken",
33-
kind: "AtSignToken",
34-
description: "The `@` sign.",
35-
tokenChoices: [
36-
"AtSign"
37-
]),
38-
Child(name: "AttributeName",
39-
kind: "Type",
40-
description: "The name of the attribute.",
41-
classification: "Attribute"),
42-
Child(name: "LeftParen",
43-
kind: "LeftParenToken",
44-
isOptional: true,
45-
tokenChoices: [
46-
"LeftParen"
47-
]),
48-
Child(name: "ArgumentList",
49-
kind: "TupleExprElementList",
50-
isOptional: true,
51-
collectionElementName: "Argument"),
52-
Child(name: "RightParen",
53-
kind: "RightParenToken",
54-
isOptional: true,
55-
tokenChoices: [
56-
"RightParen"
57-
])
58-
]),
59-
6027
Node(name: "Attribute",
6128
nameForDiagnostics: "attribute",
6229
description: "An `@` attribute.",
@@ -70,7 +37,7 @@ public let ATTRIBUTE_NODES: [Node] = [
7037
"AtSign"
7138
]),
7239
Child(name: "AttributeName",
73-
kind: "Token",
40+
kind: "Type",
7441
description: "The name of the attribute.",
7542
classification: "Attribute"),
7643
Child(name: "LeftParen",
@@ -85,6 +52,8 @@ public let ATTRIBUTE_NODES: [Node] = [
8552
description: "The arguments of the attribute. In case the attributetakes multiple arguments, they are gather in theappropriate takes first.",
8653
isOptional: true,
8754
nodeChoices: [
55+
Child(name: "ArgumentList",
56+
kind: "TupleExprElementList"),
8857
Child(name: "Token",
8958
kind: "Token"),
9059
Child(name: "Availability",
@@ -132,7 +101,7 @@ public let ATTRIBUTE_NODES: [Node] = [
132101
kind: "SyntaxCollection",
133102
element: "Syntax",
134103
elementName: "Attribute",
135-
elementChoices: ["Attribute", "CustomAttribute", "IfConfigDecl"],
104+
elementChoices: ["Attribute", "IfConfigDecl"],
136105
omitWhenEmpty: true),
137106

138107
Node(name: "SpecializeAttributeSpecList",

Sources/IDEUtils/generated/SyntaxClassification.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ extension SyntaxClassification {
8989
// Separate checks for token nodes (most common checks) versus checks for layout nodes.
9090
if childKind == .token {
9191
switch (parentKind, indexInParent) {
92-
case (.attribute, 3):
93-
return (.attribute, false)
9492
case (.availabilityVersionRestriction, 1):
9593
return (.keyword, false)
9694
case (.constrainedSugarType, 1):
@@ -122,10 +120,10 @@ extension SyntaxClassification {
122120
}
123121
} else {
124122
switch (parentKind, indexInParent) {
123+
case (.attribute, 3):
124+
return (.attribute, false)
125125
case (.availabilityVersionRestrictionListEntry, 1):
126126
return (.keyword, false)
127-
case (.customAttribute, 3):
128-
return (.attribute, false)
129127
case (.ifConfigClause, 3):
130128
return (.buildConfigId, false)
131129
case (.operatorDecl, 3):

Sources/SwiftParser/Attributes.swift

Lines changed: 66 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,48 @@ extension Parser {
2929
}
3030

3131
extension Parser {
32-
mutating func parseAttribute(hasRequiredArguments: Bool, parseArguments: (inout Parser) -> RawAttributeSyntax.Argument) -> RawAttributeListSyntax.Element {
32+
mutating func parseAttributeWithoutArguments() -> RawAttributeListSyntax.Element {
3333
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
34-
let (unexpectedBeforeAttributeName, attributeName) = self.expect(.identifier, remapping: .contextualKeyword)
35-
if hasRequiredArguments {
34+
let attributeName = self.parseType()
35+
return .attribute(
36+
RawAttributeSyntax(
37+
unexpectedBeforeAtSign,
38+
atSignToken: atSign,
39+
attributeName: attributeName,
40+
leftParen: nil,
41+
argument: nil,
42+
rightParen: nil,
43+
arena: self.arena
44+
)
45+
)
46+
}
47+
48+
enum AttributeArgumentMode {
49+
case required
50+
case customAttribute
51+
case optional
52+
}
53+
54+
mutating func parseAttribute(argumentMode: AttributeArgumentMode, parseArguments: (inout Parser) -> RawAttributeSyntax.Argument) -> RawAttributeListSyntax.Element {
55+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
56+
let attributeName = self.parseType()
57+
let shouldParseArgument: Bool
58+
switch argumentMode {
59+
case .required:
60+
shouldParseArgument = true
61+
case .customAttribute:
62+
shouldParseArgument = self.lookahead().isCustomAttributeArgument() && self.at(.leftParen, where: { !$0.isAtStartOfLine })
63+
case .optional:
64+
shouldParseArgument = self.at(.leftParen)
65+
}
66+
if shouldParseArgument {
3667
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
3768
let argument = parseArguments(&self)
3869
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
3970
return .attribute(
4071
RawAttributeSyntax(
4172
unexpectedBeforeAtSign,
4273
atSignToken: atSign,
43-
unexpectedBeforeAttributeName,
4474
attributeName: attributeName,
4575
unexpectedBeforeLeftParen,
4676
leftParen: leftParen,
@@ -50,28 +80,11 @@ extension Parser {
5080
arena: self.arena
5181
)
5282
)
53-
} else if let leftParen = self.consume(if: .leftParen) {
54-
let argument = parseArguments(&self)
55-
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
56-
return .attribute(
57-
RawAttributeSyntax(
58-
unexpectedBeforeAtSign,
59-
atSignToken: atSign,
60-
unexpectedBeforeAttributeName,
61-
attributeName: attributeName,
62-
leftParen: leftParen,
63-
argument: argument,
64-
unexpectedBeforeRightParen,
65-
rightParen: rightParen,
66-
arena: self.arena
67-
)
68-
)
6983
} else {
7084
return .attribute(
7185
RawAttributeSyntax(
7286
unexpectedBeforeAtSign,
7387
atSignToken: atSign,
74-
unexpectedBeforeAttributeName,
7588
attributeName: attributeName,
7689
leftParen: nil,
7790
argument: nil,
@@ -93,13 +106,11 @@ extension Parser {
93106
)
94107
}
95108

96-
guard let declAttr = DeclarationAttribute(rawValue: self.peek().tokenText) else {
97-
return .customAttribute(self.parseCustomAttribute())
98-
}
109+
let declAttr = DeclarationAttribute(rawValue: self.peek().tokenText)
99110

100111
switch declAttr {
101112
case .available, ._spi_available:
102-
return parseAttribute(hasRequiredArguments: true) { parser in
113+
return parseAttribute(argumentMode: .required) { parser in
103114
if parser.peek().tokenKind == .integerLiteral {
104115
return .availability(parser.parseAvailabilitySpecList(from: .available))
105116
} else if parser.peek().tokenKind == .floatingLiteral {
@@ -109,27 +120,27 @@ extension Parser {
109120
}
110121
}
111122
case .differentiable:
112-
return parseAttribute(hasRequiredArguments: true) { parser in
123+
return parseAttribute(argumentMode: .required) { parser in
113124
return .differentiableArguments(parser.parseDifferentiableAttributeArguments())
114125
}
115126
case .derivative, .transpose:
116-
return parseAttribute(hasRequiredArguments: true) { parser in
127+
return parseAttribute(argumentMode: .required) { parser in
117128
return .derivativeRegistrationArguments(parser.parseDerivativeAttributeArguments())
118129
}
119130
case .objc:
120-
return parseAttribute(hasRequiredArguments: false) { parser in
131+
return parseAttribute(argumentMode: .optional) { parser in
121132
return .objCName(parser.parseObjectiveCSelector())
122133
}
123134
case ._specialize:
124-
return parseAttribute(hasRequiredArguments: true) { parser in
135+
return parseAttribute(argumentMode: .required) { parser in
125136
return .specializeArguments(parser.parseSpecializeAttributeSpecList())
126137
}
127138
case ._private:
128-
return parseAttribute(hasRequiredArguments: true) { parser in
139+
return parseAttribute(argumentMode: .required) { parser in
129140
return .underscorePrivateAttributeArguments(parser.parseUnderscorePrivateAttributeArguments())
130141
}
131142
case ._dynamicReplacement:
132-
return parseAttribute(hasRequiredArguments: true) { parser in
143+
return parseAttribute(argumentMode: .required) { parser in
133144
return .dynamicReplacementArguments(parser.parseDynamicReplacementArguments())
134145
}
135146
case ._spi, ._effects, ._objcRuntimeName, ._projectedValueProperty, ._swift_native_objc_runtime_base, ._typeEraser, ._documentation, ._optimize, ._nonSendable, .exclusivity, .inline, ._alignment:
@@ -139,7 +150,7 @@ extension Parser {
139150
// - Keywords (e.g. `@_documentation(public)`)
140151
//
141152
// Because there seem to be very little restrictions on these parameters (they could be keywords instead of identifeirs), we just allow any token.
142-
return parseAttribute(hasRequiredArguments: true) { parser in
153+
return parseAttribute(argumentMode: .required) { parser in
143154
if !parser.at(.rightParen) {
144155
return .token(parser.consumeAnyToken())
145156
} else {
@@ -148,96 +159,71 @@ extension Parser {
148159
}
149160
case ._objcImplementation:
150161
// Similar to the above but the argument is optional
151-
return parseAttribute(hasRequiredArguments: false) { parser in
162+
return parseAttribute(argumentMode: .optional) { parser in
152163
if !parser.at(.rightParen) {
153164
return .token(parser.consumeAnyToken())
154165
} else {
155166
return .token(parser.missingToken(.identifier))
156167
}
157168
}
158169
case ._cdecl, ._silgen_name:
159-
return parseAttribute(hasRequiredArguments: true) { parser in
170+
return parseAttribute(argumentMode: .required) { parser in
160171
return .token(parser.consume(if: .stringLiteral) ?? parser.missingToken(.stringLiteral))
161172
}
162173
case ._implements:
163-
return parseAttribute(hasRequiredArguments: true) { parser in
174+
return parseAttribute(argumentMode: .required) { parser in
164175
return .implementsArguments(parser.parseImplementsAttributeArguments())
165176
}
166177
case ._semantics:
167-
return parseAttribute(hasRequiredArguments: true) { parser in
178+
return parseAttribute(argumentMode: .required) { parser in
168179
if let value = parser.consume(if: .stringLiteral) {
169180
return .token(value)
170181
} else {
171182
return .token(parser.missingToken(.stringLiteral))
172183
}
173184
}
174185
case ._backDeploy:
175-
return parseAttribute(hasRequiredArguments: true) { parser in
186+
return parseAttribute(argumentMode: .required) { parser in
176187
return .backDeployArguments(parser.parseBackDeployArguments())
177188
}
178189
case ._expose:
179-
return parseAttribute(hasRequiredArguments: true) { parser in
190+
return parseAttribute(argumentMode: .required) { parser in
180191
return .exposeAttributeArguments(parser.parseExposeArguments())
181192
}
182193
case ._originallyDefinedIn:
183-
return parseAttribute(hasRequiredArguments: true) { parser in
194+
return parseAttribute(argumentMode: .required) { parser in
184195
return .originallyDefinedInArguments(parser.parseOriginallyDefinedInArguments())
185196
}
186197
case ._unavailableFromAsync:
187-
return parseAttribute(hasRequiredArguments: false) { parser in
198+
return parseAttribute(argumentMode: .optional) { parser in
188199
return .unavailableFromAsyncArguments(parser.parseUnavailableFromAsyncArguments())
189200
}
190-
case .__objc_bridged, .__raw_doc_comment, ._alwaysEmitConformanceMetadata, ._alwaysEmitIntoClient, ._assemblyVision, ._borrowed, ._compilerInitialized, ._custom, ._disfavoredOverload, ._eagerMove, ._exported, ._fixed_layout, ._frozen, ._hasInitialValue, ._hasMissingDesignatedInitializers, ._hasStorage, ._implementationOnly, ._implicitSelfCapture, ._inheritActorContext, ._inheritsConvenienceInitializers, ._marker, ._moveOnly, ._noAllocation, ._noEagerMove, ._noImplicitCopy, ._noLocks, ._noMetadata, ._nonEphemeral, ._nonoverride, ._objc_non_lazy_realization, ._show_in_interface, ._specializeExtension, ._spiOnly, ._staticInitializeObjCMetadata, ._transparent, ._unsafeInheritExecutor, ._weakLinked, .atReasync, .atRethrows, .discardableResult, .dynamicCallable, .dynamicMemberLookup, .frozen, .GKInspectable, .globalActor, .IBAction, .IBDesignable, .IBInspectable, .IBOutlet, .IBSegueAction, .inlinable, .LLDBDebuggerFunction, .main, .noDerivative, .nonobjc, .NSApplicationMain, .NSCopying,
191-
.NSManaged, .objcMembers, .preconcurrency, .propertyWrapper, .requires_stored_property_inits, .resultBuilder, .runtimeMetadata, .Sendable, .testable, .typeWrapper, .typeWrapperIgnored, .UIApplicationMain, .unsafe_no_objc_tagged_pointer, .usableFromInline, .warn_unqualified_access,
192-
.__synthesized_protocol, ._clangImporterSynthesizedType, ._forbidSerializingReference, ._restatedObjCConformance:
201+
case .atRethrows:
193202
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
194-
let (unexpectedBeforeAttributeName, attributeName) = self.expectIdentifierOrRethrows()
203+
let (unexpectedBeforeAttributeName, attributeName) = self.expect(.rethrowsKeyword, remapping: .identifier)
195204
return .attribute(
196205
RawAttributeSyntax(
197206
unexpectedBeforeAtSign,
198207
atSignToken: atSign,
199208
unexpectedBeforeAttributeName,
200-
attributeName: attributeName,
209+
attributeName: RawTypeSyntax(RawSimpleTypeIdentifierSyntax(name: attributeName, genericArgumentClause: nil, arena: self.arena)),
201210
leftParen: nil,
202211
argument: nil,
203212
rightParen: nil,
204213
arena: self.arena
205214
)
206215
)
216+
case .__objc_bridged, .__raw_doc_comment, ._alwaysEmitConformanceMetadata, ._alwaysEmitIntoClient, ._assemblyVision, ._borrowed, ._compilerInitialized, ._custom, ._disfavoredOverload, ._eagerMove, ._exported, ._fixed_layout, ._frozen, ._hasInitialValue, ._hasMissingDesignatedInitializers, ._hasStorage, ._implementationOnly, ._implicitSelfCapture, ._inheritActorContext, ._inheritsConvenienceInitializers, ._marker, ._moveOnly, ._noAllocation, ._noEagerMove, ._noImplicitCopy, ._noLocks, ._noMetadata, ._nonEphemeral, ._nonoverride, ._objc_non_lazy_realization, ._show_in_interface, ._specializeExtension, ._spiOnly, ._staticInitializeObjCMetadata, ._transparent, ._unsafeInheritExecutor, ._weakLinked, .atReasync, .discardableResult, .dynamicCallable, .dynamicMemberLookup, .frozen, .GKInspectable, .globalActor, .IBAction, .IBDesignable, .IBInspectable, .IBOutlet, .IBSegueAction, .inlinable, .LLDBDebuggerFunction, .main, .noDerivative, .nonobjc, .NSApplicationMain, .NSCopying,
217+
.NSManaged, .objcMembers, .preconcurrency, .propertyWrapper, .requires_stored_property_inits, .resultBuilder, .runtimeMetadata, .Sendable, .testable, .typeWrapper, .typeWrapperIgnored, .UIApplicationMain, .unsafe_no_objc_tagged_pointer, .usableFromInline, .warn_unqualified_access,
218+
.__synthesized_protocol, ._clangImporterSynthesizedType, ._forbidSerializingReference, ._restatedObjCConformance:
219+
return parseAttributeWithoutArguments()
220+
case nil:
221+
return parseAttribute(argumentMode: .customAttribute) { parser in
222+
let arguments = parser.parseArgumentListElements(pattern: .none)
223+
return .argumentList(RawTupleExprElementListSyntax(elements: arguments, arena: parser.arena))
224+
}
207225
}
208226
}
209-
210-
mutating func parseCustomAttribute() -> RawCustomAttributeSyntax {
211-
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
212-
let attrName = self.parseType()
213-
214-
// Custom attributes are stricter than normal attributes about their
215-
// argument lists "immediately" following the attribute name.
216-
guard self.lookahead().isCustomAttributeArgument(),
217-
let leftParen = self.consume(if: .leftParen, where: { !$0.isAtStartOfLine })
218-
else {
219-
return RawCustomAttributeSyntax(
220-
atSignToken: atSign,
221-
attributeName: attrName,
222-
leftParen: nil,
223-
argumentList: nil,
224-
rightParen: nil,
225-
arena: self.arena
226-
)
227-
}
228-
let arguments = self.parseArgumentListElements(pattern: .none)
229-
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
230-
return RawCustomAttributeSyntax(
231-
unexpectedBeforeAtSign,
232-
atSignToken: atSign,
233-
attributeName: attrName,
234-
leftParen: leftParen,
235-
argumentList: RawTupleExprElementListSyntax(elements: arguments, arena: self.arena),
236-
unexpectedBeforeRightParen,
237-
rightParen: rightParen,
238-
arena: self.arena
239-
)
240-
}
241227
}
242228

243229
extension Parser {
@@ -253,7 +239,7 @@ extension Parser {
253239
unexpectedBeforeAtSign,
254240
atSignToken: atSign,
255241
unexpectedBeforeDifferentiable,
256-
attributeName: differentiable,
242+
attributeName: RawTypeSyntax(RawSimpleTypeIdentifierSyntax(name: differentiable, genericArgumentClause: nil, arena: self.arena)),
257243
unexpectedBeforeLeftParen,
258244
leftParen: leftParen,
259245
argument: .differentiableArguments(argument),
@@ -424,7 +410,7 @@ extension Parser {
424410
unexpectedBeforeAtSign,
425411
atSignToken: atSign,
426412
unexpectedBeforeDerivative,
427-
attributeName: derivative,
413+
attributeName: RawTypeSyntax(RawSimpleTypeIdentifierSyntax(name: derivative, genericArgumentClause: nil, arena: self.arena)),
428414
unexpectedBeforeLeftParen,
429415
leftParen: leftParen,
430416
argument: .derivativeRegistrationArguments(argument),
@@ -446,7 +432,7 @@ extension Parser {
446432
unexpectedBeforeAtSign,
447433
atSignToken: atSign,
448434
unexpectedBeforeTranspose,
449-
attributeName: transpose,
435+
attributeName: RawTypeSyntax(RawSimpleTypeIdentifierSyntax(name: transpose, genericArgumentClause: nil, arena: self.arena)),
450436
unexpectedBeforeLeftParen,
451437
leftParen: leftParen,
452438
argument: .derivativeRegistrationArguments(argument),

Sources/SwiftParser/Statements.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ extension Parser {
837837
unknownAttr = RawAttributeSyntax(
838838
atSignToken: at,
839839
unexpectedBeforeIdent,
840-
attributeName: ident,
840+
attributeName: RawTypeSyntax(RawSimpleTypeIdentifierSyntax(name: ident, genericArgumentClause: nil, arena: self.arena)),
841841
leftParen: nil,
842842
argument: nil,
843843
rightParen: nil,

0 commit comments

Comments
 (0)