@@ -29,18 +29,48 @@ extension Parser {
29
29
}
30
30
31
31
extension Parser {
32
- mutating func parseAttribute ( hasRequiredArguments : Bool , parseArguments : ( inout Parser ) -> RawAttributeSyntax . Argument ) -> RawAttributeListSyntax . Element {
32
+ mutating func parseAttributeWithoutArguments ( ) -> RawAttributeListSyntax . Element {
33
33
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 {
36
67
let ( unexpectedBeforeLeftParen, leftParen) = self . expect ( . leftParen)
37
68
let argument = parseArguments ( & self )
38
69
let ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
39
70
return . attribute(
40
71
RawAttributeSyntax (
41
72
unexpectedBeforeAtSign,
42
73
atSignToken: atSign,
43
- unexpectedBeforeAttributeName,
44
74
attributeName: attributeName,
45
75
unexpectedBeforeLeftParen,
46
76
leftParen: leftParen,
@@ -50,28 +80,11 @@ extension Parser {
50
80
arena: self . arena
51
81
)
52
82
)
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
- )
69
83
} else {
70
84
return . attribute(
71
85
RawAttributeSyntax (
72
86
unexpectedBeforeAtSign,
73
87
atSignToken: atSign,
74
- unexpectedBeforeAttributeName,
75
88
attributeName: attributeName,
76
89
leftParen: nil ,
77
90
argument: nil ,
@@ -93,13 +106,11 @@ extension Parser {
93
106
)
94
107
}
95
108
96
- guard let declAttr = DeclarationAttribute ( rawValue: self . peek ( ) . tokenText) else {
97
- return . customAttribute( self . parseCustomAttribute ( ) )
98
- }
109
+ let declAttr = DeclarationAttribute ( rawValue: self . peek ( ) . tokenText)
99
110
100
111
switch declAttr {
101
112
case . available, . _spi_available:
102
- return parseAttribute ( hasRequiredArguments : true ) { parser in
113
+ return parseAttribute ( argumentMode : . required ) { parser in
103
114
if parser. peek ( ) . tokenKind == . integerLiteral {
104
115
return . availability( parser. parseAvailabilitySpecList ( from: . available) )
105
116
} else if parser. peek ( ) . tokenKind == . floatingLiteral {
@@ -109,27 +120,27 @@ extension Parser {
109
120
}
110
121
}
111
122
case . differentiable:
112
- return parseAttribute ( hasRequiredArguments : true ) { parser in
123
+ return parseAttribute ( argumentMode : . required ) { parser in
113
124
return . differentiableArguments( parser. parseDifferentiableAttributeArguments ( ) )
114
125
}
115
126
case . derivative, . transpose:
116
- return parseAttribute ( hasRequiredArguments : true ) { parser in
127
+ return parseAttribute ( argumentMode : . required ) { parser in
117
128
return . derivativeRegistrationArguments( parser. parseDerivativeAttributeArguments ( ) )
118
129
}
119
130
case . objc:
120
- return parseAttribute ( hasRequiredArguments : false ) { parser in
131
+ return parseAttribute ( argumentMode : . optional ) { parser in
121
132
return . objCName( parser. parseObjectiveCSelector ( ) )
122
133
}
123
134
case . _specialize:
124
- return parseAttribute ( hasRequiredArguments : true ) { parser in
135
+ return parseAttribute ( argumentMode : . required ) { parser in
125
136
return . specializeArguments( parser. parseSpecializeAttributeSpecList ( ) )
126
137
}
127
138
case . _private:
128
- return parseAttribute ( hasRequiredArguments : true ) { parser in
139
+ return parseAttribute ( argumentMode : . required ) { parser in
129
140
return . underscorePrivateAttributeArguments( parser. parseUnderscorePrivateAttributeArguments ( ) )
130
141
}
131
142
case . _dynamicReplacement:
132
- return parseAttribute ( hasRequiredArguments : true ) { parser in
143
+ return parseAttribute ( argumentMode : . required ) { parser in
133
144
return . dynamicReplacementArguments( parser. parseDynamicReplacementArguments ( ) )
134
145
}
135
146
case . _spi, . _effects, . _objcRuntimeName, . _projectedValueProperty, . _swift_native_objc_runtime_base, . _typeEraser, . _documentation, . _optimize, . _nonSendable, . exclusivity, . inline, . _alignment:
@@ -139,7 +150,7 @@ extension Parser {
139
150
// - Keywords (e.g. `@_documentation(public)`)
140
151
//
141
152
// 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
143
154
if !parser. at ( . rightParen) {
144
155
return . token( parser. consumeAnyToken ( ) )
145
156
} else {
@@ -148,96 +159,71 @@ extension Parser {
148
159
}
149
160
case . _objcImplementation:
150
161
// Similar to the above but the argument is optional
151
- return parseAttribute ( hasRequiredArguments : false ) { parser in
162
+ return parseAttribute ( argumentMode : . optional ) { parser in
152
163
if !parser. at ( . rightParen) {
153
164
return . token( parser. consumeAnyToken ( ) )
154
165
} else {
155
166
return . token( parser. missingToken ( . identifier) )
156
167
}
157
168
}
158
169
case . _cdecl, . _silgen_name:
159
- return parseAttribute ( hasRequiredArguments : true ) { parser in
170
+ return parseAttribute ( argumentMode : . required ) { parser in
160
171
return . token( parser. consume ( if: . stringLiteral) ?? parser. missingToken ( . stringLiteral) )
161
172
}
162
173
case . _implements:
163
- return parseAttribute ( hasRequiredArguments : true ) { parser in
174
+ return parseAttribute ( argumentMode : . required ) { parser in
164
175
return . implementsArguments( parser. parseImplementsAttributeArguments ( ) )
165
176
}
166
177
case . _semantics:
167
- return parseAttribute ( hasRequiredArguments : true ) { parser in
178
+ return parseAttribute ( argumentMode : . required ) { parser in
168
179
if let value = parser. consume ( if: . stringLiteral) {
169
180
return . token( value)
170
181
} else {
171
182
return . token( parser. missingToken ( . stringLiteral) )
172
183
}
173
184
}
174
185
case . _backDeploy:
175
- return parseAttribute ( hasRequiredArguments : true ) { parser in
186
+ return parseAttribute ( argumentMode : . required ) { parser in
176
187
return . backDeployArguments( parser. parseBackDeployArguments ( ) )
177
188
}
178
189
case . _expose:
179
- return parseAttribute ( hasRequiredArguments : true ) { parser in
190
+ return parseAttribute ( argumentMode : . required ) { parser in
180
191
return . exposeAttributeArguments( parser. parseExposeArguments ( ) )
181
192
}
182
193
case . _originallyDefinedIn:
183
- return parseAttribute ( hasRequiredArguments : true ) { parser in
194
+ return parseAttribute ( argumentMode : . required ) { parser in
184
195
return . originallyDefinedInArguments( parser. parseOriginallyDefinedInArguments ( ) )
185
196
}
186
197
case . _unavailableFromAsync:
187
- return parseAttribute ( hasRequiredArguments : false ) { parser in
198
+ return parseAttribute ( argumentMode : . optional ) { parser in
188
199
return . unavailableFromAsyncArguments( parser. parseUnavailableFromAsyncArguments ( ) )
189
200
}
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:
193
202
let ( unexpectedBeforeAtSign, atSign) = self . expect ( . atSign)
194
- let ( unexpectedBeforeAttributeName, attributeName) = self . expectIdentifierOrRethrows ( )
203
+ let ( unexpectedBeforeAttributeName, attributeName) = self . expect ( . rethrowsKeyword , remapping : . identifier )
195
204
return . attribute(
196
205
RawAttributeSyntax (
197
206
unexpectedBeforeAtSign,
198
207
atSignToken: atSign,
199
208
unexpectedBeforeAttributeName,
200
- attributeName: attributeName,
209
+ attributeName: RawTypeSyntax ( RawSimpleTypeIdentifierSyntax ( name : attributeName, genericArgumentClause : nil , arena : self . arena ) ) ,
201
210
leftParen: nil ,
202
211
argument: nil ,
203
212
rightParen: nil ,
204
213
arena: self . arena
205
214
)
206
215
)
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
+ }
207
225
}
208
226
}
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
- }
241
227
}
242
228
243
229
extension Parser {
@@ -253,7 +239,7 @@ extension Parser {
253
239
unexpectedBeforeAtSign,
254
240
atSignToken: atSign,
255
241
unexpectedBeforeDifferentiable,
256
- attributeName: differentiable,
242
+ attributeName: RawTypeSyntax ( RawSimpleTypeIdentifierSyntax ( name : differentiable, genericArgumentClause : nil , arena : self . arena ) ) ,
257
243
unexpectedBeforeLeftParen,
258
244
leftParen: leftParen,
259
245
argument: . differentiableArguments( argument) ,
@@ -424,7 +410,7 @@ extension Parser {
424
410
unexpectedBeforeAtSign,
425
411
atSignToken: atSign,
426
412
unexpectedBeforeDerivative,
427
- attributeName: derivative,
413
+ attributeName: RawTypeSyntax ( RawSimpleTypeIdentifierSyntax ( name : derivative, genericArgumentClause : nil , arena : self . arena ) ) ,
428
414
unexpectedBeforeLeftParen,
429
415
leftParen: leftParen,
430
416
argument: . derivativeRegistrationArguments( argument) ,
@@ -446,7 +432,7 @@ extension Parser {
446
432
unexpectedBeforeAtSign,
447
433
atSignToken: atSign,
448
434
unexpectedBeforeTranspose,
449
- attributeName: transpose,
435
+ attributeName: RawTypeSyntax ( RawSimpleTypeIdentifierSyntax ( name : transpose, genericArgumentClause : nil , arena : self . arena ) ) ,
450
436
unexpectedBeforeLeftParen,
451
437
leftParen: leftParen,
452
438
argument: . derivativeRegistrationArguments( argument) ,
0 commit comments