@@ -5,7 +5,7 @@ use super::{FollowedByType, Parser, PathStyle};
5
5
use crate :: maybe_whole;
6
6
7
7
use rustc_ast:: ast:: { self , AttrStyle , AttrVec , Attribute , Ident , DUMMY_NODE_ID } ;
8
- use rustc_ast:: ast:: { AssocItem , AssocItemKind , ForeignItemKind , Item , ItemKind } ;
8
+ use rustc_ast:: ast:: { AssocItem , AssocItemKind , ForeignItemKind , Item , ItemKind , Mod } ;
9
9
use rustc_ast:: ast:: {
10
10
Async , Const , Defaultness , IsAuto , PathSegment , Unsafe , UseTree , UseTreeKind ,
11
11
} ;
@@ -15,7 +15,7 @@ use rustc_ast::ast::{
15
15
use rustc_ast:: ast:: { EnumDef , Generics , StructField , TraitRef , Ty , TyKind , Variant , VariantData } ;
16
16
use rustc_ast:: ast:: { FnHeader , ForeignItem , Mutability , Visibility , VisibilityKind } ;
17
17
use rustc_ast:: ptr:: P ;
18
- use rustc_ast:: token;
18
+ use rustc_ast:: token:: { self , TokenKind } ;
19
19
use rustc_ast:: tokenstream:: { DelimSpan , TokenStream , TokenTree } ;
20
20
use rustc_ast_pretty:: pprust;
21
21
use rustc_errors:: { struct_span_err, Applicability , PResult , StashKey } ;
@@ -27,6 +27,61 @@ use log::debug;
27
27
use std:: convert:: TryFrom ;
28
28
use std:: mem;
29
29
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
+
30
85
pub ( super ) type ItemInfo = ( Ident , ItemKind ) ;
31
86
32
87
impl < ' a > Parser < ' a > {
0 commit comments