@@ -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,38 @@ 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( InterfaceSyntax . parse ( 
144+                 lexer:  & lexer,  documents:  documents,  attributes:  attributes
145+             ) ) 
142146        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) ) ) 
147+             return  try   . world( WorldSyntax . parse ( 
148+                 lexer:  & lexer,  documents:  documents,  attributes:  attributes
149+             ) ) 
150+         case  . use:  return  try   . use( . init( syntax:  . parse( 
151+             lexer:  & lexer,  documents:  documents,  attributes:  attributes
152+         ) ) ) 
145153        default : 
146154            throw  ParseError ( description:  " `world`, `interface` or `use` expected " ) 
147155        } 
148156    } 
149157} 
150158
151159extension  TopLevelUseSyntax  { 
152-     static  func  parse( lexer:  inout  Lexer ,  documents:  DocumentsSyntax )  throws  ->  TopLevelUseSyntax  { 
160+     static  func  parse( 
161+         lexer:  inout  Lexer , 
162+         documents:  DocumentsSyntax ,  attributes:  [ AttributeSyntax ] 
163+     )  throws  ->  TopLevelUseSyntax  { 
153164        try   lexer. expect ( . use) 
154165        let  item  =  try   UsePathSyntax . parse ( lexer:  & lexer) 
155166        var  asName :  Identifier ? 
156167        if  lexer. eat ( . as)  { 
157168            asName =  try   . parse( lexer:  & lexer) 
158169        } 
159-         return  TopLevelUseSyntax ( item:  item,  asName:  asName) 
170+         try   lexer. expectSemicolon ( ) 
171+         return  TopLevelUseSyntax ( attributes:  attributes,  item:  item,  asName:  asName) 
160172    } 
161173} 
162174
@@ -179,7 +191,8 @@ extension UseSyntax {
179191                break 
180192            } 
181193        } 
182-         return  . init( syntax:  UseSyntax ( from:  from,  names:  names) ) 
194+         try   lexer. expectSemicolon ( ) 
195+         return  . init( syntax:  UseSyntax ( attributes:  [ ] ,  from:  from,  names:  names) ) 
183196    } 
184197} 
185198
@@ -222,3 +235,70 @@ extension DocumentsSyntax {
222235        return  DocumentsSyntax ( comments:  comments) 
223236    } 
224237} 
238+ 
239+ extension  AttributeSyntax  { 
240+     static  func  parseItems( lexer:  inout  Lexer )  throws  ->  [ AttributeSyntax ]  { 
241+         var  items :  [ AttributeSyntax ]  =  [ ] 
242+         while  lexer. eat ( . at)  { 
243+             let  id  =  try   Identifier . parse ( lexer:  & lexer) 
244+             let  item :  AttributeSyntax 
245+             switch  id. text { 
246+             case  " since " :  item =  . since( try   . parse( lexer:  & lexer,  id:  id) ) 
247+             case  " unstable " :  item =  . unstable( try   . parse( lexer:  & lexer,  id:  id) ) 
248+             case  " deprecated " :  item =  . deprecated( try   . parse( lexer:  & lexer,  id:  id) ) 
249+             default : 
250+                 throw  ParseError ( description:  " Unexpected attribute:  \( id. text) " ) 
251+             } 
252+             items. append ( item) 
253+         } 
254+         return  items
255+     } 
256+ } 
257+ 
258+ extension  SinceAttributeSyntax  { 
259+     static  func  parse( lexer:  inout  Lexer ,  id:  Identifier )  throws  ->  SinceAttributeSyntax  { 
260+         try   lexer. expect ( . leftParen) 
261+         try   lexer. expectIdentifier ( " version " ) 
262+         try   lexer. expect ( . equals) 
263+         let  version  =  try   Version . parse ( lexer:  & lexer) 
264+         var  feature :  Identifier ? 
265+         if  lexer. eat ( . comma)  { 
266+             try   lexer. expectIdentifier ( " feature " ) 
267+             try   lexer. expect ( . equals) 
268+             feature =  try   Identifier . parse ( lexer:  & lexer) 
269+         } 
270+         try   lexer. expect ( . rightParen) 
271+         return  SinceAttributeSyntax ( 
272+             version:  version,  feature:  feature, 
273+             textRange:  id. textRange. lowerBound..< lexer. cursor. nextIndex
274+         ) 
275+     } 
276+ } 
277+ 
278+ extension  UnstableAttributeSyntax  { 
279+     static  func  parse( lexer:  inout  Lexer ,  id:  Identifier )  throws  ->  UnstableAttributeSyntax  { 
280+         try   lexer. expect ( . leftParen) 
281+         try   lexer. expectIdentifier ( " feature " ) 
282+         try   lexer. expect ( . equals) 
283+         let  feature  =  try   Identifier . parse ( lexer:  & lexer) 
284+         try   lexer. expect ( . rightParen) 
285+         return  UnstableAttributeSyntax ( 
286+             textRange:  id. textRange. lowerBound..< lexer. cursor. nextIndex, 
287+             feature:  feature
288+         ) 
289+     } 
290+ } 
291+ 
292+ extension  DeprecatedAttributeSyntax  { 
293+     static  func  parse( lexer:  inout  Lexer ,  id:  Identifier )  throws  ->  DeprecatedAttributeSyntax  { 
294+         try   lexer. expect ( . leftParen) 
295+         try   lexer. expectIdentifier ( " version " ) 
296+         try   lexer. expect ( . equals) 
297+         let  version  =  try   Version . parse ( lexer:  & lexer) 
298+         try   lexer. expect ( . rightParen) 
299+         return  DeprecatedAttributeSyntax ( 
300+             textRange:  id. textRange. lowerBound..< lexer. cursor. nextIndex, 
301+             version:  version
302+         ) 
303+     } 
304+ } 
0 commit comments