@@ -3,6 +3,7 @@ extension SourceFileSyntax {
33 var packageId : PackageNameSyntax ?
44 if lexer. peek ( ) ? . kind == . package {
55 packageId = try PackageNameSyntax . parse ( lexer: & lexer)
6+ try lexer. expectSemicolon ( )
67 }
78
89 var items : [ ASTItemSyntax ] = [ ]
@@ -136,27 +137,43 @@ extension ASTItemSyntax {
136137 static func parse(
137138 lexer: inout Lexer , documents: DocumentsSyntax
138139 ) throws -> ASTItemSyntax {
140+ let attributes = try AttributeSyntax . parseItems ( lexer: & lexer)
139141 switch lexer. peek ( ) ? . kind {
140142 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+ ) )
142147 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+ ) ) )
145158 default :
146159 throw ParseError ( description: " `world`, `interface` or `use` expected " )
147160 }
148161 }
149162}
150163
151164extension 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 {
153169 try lexer. expect ( . use)
154170 let item = try UsePathSyntax . parse ( lexer: & lexer)
155171 var asName : Identifier ?
156172 if lexer. eat ( . as) {
157173 asName = try . parse( lexer: & lexer)
158174 }
159- return TopLevelUseSyntax ( item: item, asName: asName)
175+ try lexer. expectSemicolon ( )
176+ return TopLevelUseSyntax ( attributes: attributes, item: item, asName: asName)
160177 }
161178}
162179
@@ -179,7 +196,8 @@ extension UseSyntax {
179196 break
180197 }
181198 }
182- return . init( syntax: UseSyntax ( from: from, names: names) )
199+ try lexer. expectSemicolon ( )
200+ return . init( syntax: UseSyntax ( attributes: [ ] , from: from, names: names) )
183201 }
184202}
185203
@@ -222,3 +240,70 @@ extension DocumentsSyntax {
222240 return DocumentsSyntax ( comments: comments)
223241 }
224242}
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