@@ -4,14 +4,18 @@ use super::{FollowedByType, Parser, PathStyle};
44
55use crate :: maybe_whole;
66
7- use rustc_ast:: ast:: { self , Async , AttrStyle , AttrVec , Attribute , Ident , DUMMY_NODE_ID } ;
8- use rustc_ast:: ast:: { AssocItem , AssocItemKind , ForeignItemKind , Item , ItemKind } ;
9- use rustc_ast:: ast:: { BindingMode , Block , FnDecl , FnSig , MacArgs , MacCall , MacDelimiter , Param } ;
10- use rustc_ast:: ast:: { Const , Defaultness , IsAuto , PathSegment , Unsafe , UseTree , UseTreeKind } ;
7+ use rustc_ast:: ast:: { self , AttrStyle , AttrVec , Attribute , Ident , DUMMY_NODE_ID } ;
8+ use rustc_ast:: ast:: { AssocItem , AssocItemKind , ForeignItemKind , Item , ItemKind , Mod } ;
9+ use rustc_ast:: ast:: {
10+ Async , Const , Defaultness , IsAuto , PathSegment , Unsafe , UseTree , UseTreeKind ,
11+ } ;
12+ use rustc_ast:: ast:: {
13+ BindingMode , Block , FnDecl , FnSig , MacArgs , MacCall , MacDelimiter , Param , SelfKind ,
14+ } ;
1115use rustc_ast:: ast:: { EnumDef , Generics , StructField , TraitRef , Ty , TyKind , Variant , VariantData } ;
1216use rustc_ast:: ast:: { FnHeader , ForeignItem , Mutability , SelfKind , Visibility , VisibilityKind } ;
1317use rustc_ast:: ptr:: P ;
14- use rustc_ast:: token;
18+ use rustc_ast:: token:: { self , TokenKind } ;
1519use rustc_ast:: tokenstream:: { DelimSpan , TokenStream , TokenTree } ;
1620use rustc_ast_pretty:: pprust;
1721use rustc_errors:: { struct_span_err, Applicability , PResult , StashKey } ;
@@ -23,6 +27,61 @@ use log::debug;
2327use std:: convert:: TryFrom ;
2428use std:: mem;
2529
30+ impl < ' a > Parser < ' a > {
31+ /// Parses a source module as a crate. This is the main entry point for the parser.
32+ pub fn parse_crate_mod ( & mut self ) -> PResult < ' a , ast:: Crate > {
33+ let lo = self . token . span ;
34+ let ( module, attrs) = self . parse_mod ( & token:: Eof ) ?;
35+ let span = lo. to ( self . token . span ) ;
36+ let proc_macros = Vec :: new ( ) ; // Filled in by `proc_macro_harness::inject()`.
37+ Ok ( ast:: Crate { attrs, module, span, proc_macros } )
38+ }
39+
40+ /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
41+ pub ( super ) fn parse_item_mod ( & mut self , attrs : & mut Vec < Attribute > ) -> PResult < ' a , ItemInfo > {
42+ let id = self . parse_ident ( ) ?;
43+ let ( module, mut inner_attrs) = if self . eat ( & token:: Semi ) {
44+ Default :: default ( )
45+ } else {
46+ self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
47+ self . parse_mod ( & token:: CloseDelim ( token:: Brace ) ) ?
48+ } ;
49+ attrs. append ( & mut inner_attrs) ;
50+ Ok ( ( id, ItemKind :: Mod ( module) ) )
51+ }
52+
53+ /// Parses the contents of a module (inner attributes followed by module items).
54+ pub fn parse_mod ( & mut self , term : & TokenKind ) -> PResult < ' a , ( Mod , Vec < Attribute > ) > {
55+ let lo = self . token . span ;
56+ let attrs = self . parse_inner_attributes ( ) ?;
57+ let module = self . parse_mod_items ( term, lo) ?;
58+ Ok ( ( module, attrs) )
59+ }
60+
61+ /// Given a termination token, parses all of the items in a module.
62+ fn parse_mod_items ( & mut self , term : & TokenKind , inner_lo : Span ) -> PResult < ' a , Mod > {
63+ let mut items = vec ! [ ] ;
64+ while let Some ( item) = self . parse_item ( ) ? {
65+ items. push ( item) ;
66+ self . maybe_consume_incorrect_semicolon ( & items) ;
67+ }
68+
69+ if !self . eat ( term) {
70+ let token_str = super :: token_descr ( & self . token ) ;
71+ if !self . maybe_consume_incorrect_semicolon ( & items) {
72+ let msg = & format ! ( "expected item, found {}" , token_str) ;
73+ let mut err = self . struct_span_err ( self . token . span , msg) ;
74+ err. span_label ( self . token . span , "expected item" ) ;
75+ return Err ( err) ;
76+ }
77+ }
78+
79+ let hi = if self . token . span . is_dummy ( ) { inner_lo } else { self . prev_token . span } ;
80+
81+ Ok ( Mod { inner : inner_lo. to ( hi) , items, inline : true } )
82+ }
83+ }
84+
2685pub ( super ) type ItemInfo = ( Ident , ItemKind ) ;
2786
2887impl < ' a > Parser < ' a > {
0 commit comments