@@ -3,6 +3,7 @@ extension SourceFileSyntax {
3
3
var packageId : PackageNameSyntax ?
4
4
if lexer. peek ( ) ? . kind == . package {
5
5
packageId = try PackageNameSyntax . parse ( lexer: & lexer)
6
+ try lexer. expectSemicolon ( )
6
7
}
7
8
8
9
var items : [ ASTItemSyntax ] = [ ]
@@ -136,27 +137,43 @@ extension ASTItemSyntax {
136
137
static func parse(
137
138
lexer: inout Lexer , documents: DocumentsSyntax
138
139
) throws -> ASTItemSyntax {
140
+ let attributes = try AttributeSyntax . parseItems ( lexer: & lexer)
139
141
switch lexer. peek ( ) ? . kind {
140
142
case . interface:
141
- return try . interface( InterfaceSyntax . parse ( lexer: & lexer, documents: documents) )
143
+ return try . interface(
144
+ InterfaceSyntax . parse (
145
+ lexer: & lexer, documents: documents, attributes: attributes
146
+ ) )
142
147
case . world:
143
- return try . world( WorldSyntax . parse ( lexer: & lexer, documents: documents) )
144
- case . use: return try . use( . init( syntax: . parse( lexer: & lexer, documents: documents) ) )
148
+ return try . world(
149
+ WorldSyntax . parse (
150
+ lexer: & lexer, documents: documents, attributes: attributes
151
+ ) )
152
+ case . use:
153
+ return try . use(
154
+ . init(
155
+ syntax: . parse(
156
+ lexer: & lexer, documents: documents, attributes: attributes
157
+ ) ) )
145
158
default :
146
159
throw ParseError ( description: " `world`, `interface` or `use` expected " )
147
160
}
148
161
}
149
162
}
150
163
151
164
extension TopLevelUseSyntax {
152
- static func parse( lexer: inout Lexer , documents: DocumentsSyntax ) throws -> TopLevelUseSyntax {
165
+ static func parse(
166
+ lexer: inout Lexer ,
167
+ documents: DocumentsSyntax , attributes: [ AttributeSyntax ]
168
+ ) throws -> TopLevelUseSyntax {
153
169
try lexer. expect ( . use)
154
170
let item = try UsePathSyntax . parse ( lexer: & lexer)
155
171
var asName : Identifier ?
156
172
if lexer. eat ( . as) {
157
173
asName = try . parse( lexer: & lexer)
158
174
}
159
- return TopLevelUseSyntax ( item: item, asName: asName)
175
+ try lexer. expectSemicolon ( )
176
+ return TopLevelUseSyntax ( attributes: attributes, item: item, asName: asName)
160
177
}
161
178
}
162
179
@@ -179,7 +196,8 @@ extension UseSyntax {
179
196
break
180
197
}
181
198
}
182
- return . init( syntax: UseSyntax ( from: from, names: names) )
199
+ try lexer. expectSemicolon ( )
200
+ return . init( syntax: UseSyntax ( attributes: [ ] , from: from, names: names) )
183
201
}
184
202
}
185
203
@@ -222,3 +240,70 @@ extension DocumentsSyntax {
222
240
return DocumentsSyntax ( comments: comments)
223
241
}
224
242
}
243
+
244
+ extension AttributeSyntax {
245
+ static func parseItems( lexer: inout Lexer ) throws -> [ AttributeSyntax ] {
246
+ var items : [ AttributeSyntax ] = [ ]
247
+ while lexer. eat ( . at) {
248
+ let id = try Identifier . parse ( lexer: & lexer)
249
+ let item : AttributeSyntax
250
+ switch id. text {
251
+ case " since " : item = . since( try . parse( lexer: & lexer, id: id) )
252
+ case " unstable " : item = . unstable( try . parse( lexer: & lexer, id: id) )
253
+ case " deprecated " : item = . deprecated( try . parse( lexer: & lexer, id: id) )
254
+ default :
255
+ throw ParseError ( description: " Unexpected attribute: \( id. text) " )
256
+ }
257
+ items. append ( item)
258
+ }
259
+ return items
260
+ }
261
+ }
262
+
263
+ extension SinceAttributeSyntax {
264
+ static func parse( lexer: inout Lexer , id: Identifier ) throws -> SinceAttributeSyntax {
265
+ try lexer. expect ( . leftParen)
266
+ try lexer. expectIdentifier ( " version " )
267
+ try lexer. expect ( . equals)
268
+ let version = try Version . parse ( lexer: & lexer)
269
+ var feature : Identifier ?
270
+ if lexer. eat ( . comma) {
271
+ try lexer. expectIdentifier ( " feature " )
272
+ try lexer. expect ( . equals)
273
+ feature = try Identifier . parse ( lexer: & lexer)
274
+ }
275
+ try lexer. expect ( . rightParen)
276
+ return SinceAttributeSyntax (
277
+ version: version, feature: feature,
278
+ textRange: id. textRange. lowerBound..< lexer. cursor. nextIndex
279
+ )
280
+ }
281
+ }
282
+
283
+ extension UnstableAttributeSyntax {
284
+ static func parse( lexer: inout Lexer , id: Identifier ) throws -> UnstableAttributeSyntax {
285
+ try lexer. expect ( . leftParen)
286
+ try lexer. expectIdentifier ( " feature " )
287
+ try lexer. expect ( . equals)
288
+ let feature = try Identifier . parse ( lexer: & lexer)
289
+ try lexer. expect ( . rightParen)
290
+ return UnstableAttributeSyntax (
291
+ textRange: id. textRange. lowerBound..< lexer. cursor. nextIndex,
292
+ feature: feature
293
+ )
294
+ }
295
+ }
296
+
297
+ extension DeprecatedAttributeSyntax {
298
+ static func parse( lexer: inout Lexer , id: Identifier ) throws -> DeprecatedAttributeSyntax {
299
+ try lexer. expect ( . leftParen)
300
+ try lexer. expectIdentifier ( " version " )
301
+ try lexer. expect ( . equals)
302
+ let version = try Version . parse ( lexer: & lexer)
303
+ try lexer. expect ( . rightParen)
304
+ return DeprecatedAttributeSyntax (
305
+ textRange: id. textRange. lowerBound..< lexer. cursor. nextIndex,
306
+ version: version
307
+ )
308
+ }
309
+ }
0 commit comments