@@ -7,15 +7,17 @@ extern crate rustc_parse;
7
7
extern crate rustc_session;
8
8
extern crate rustc_span;
9
9
10
- use rustc_ast:: ast:: { DUMMY_NODE_ID , Expr } ;
11
- use rustc_ast:: mut_visit:: MutVisitor ;
10
+ use rustc_ast:: ast:: { AttrKind , Attribute , DUMMY_NODE_ID , Expr } ;
11
+ use rustc_ast:: mut_visit:: { self , MutVisitor } ;
12
12
use rustc_ast:: node_id:: NodeId ;
13
13
use rustc_ast:: ptr:: P ;
14
- use rustc_ast:: token;
14
+ use rustc_ast:: token:: { self , Token } ;
15
+ use rustc_ast:: tokenstream:: { AttrTokenStream , AttrTokenTree , LazyAttrTokenStream } ;
15
16
use rustc_errors:: Diag ;
16
17
use rustc_parse:: parser:: Recovery ;
17
18
use rustc_session:: parse:: ParseSess ;
18
- use rustc_span:: { DUMMY_SP , FileName , Span } ;
19
+ use rustc_span:: { AttrId , DUMMY_SP , FileName , Span } ;
20
+ use std:: sync:: Arc ;
19
21
20
22
pub fn parse_expr ( psess : & ParseSess , source_code : & str ) -> Option < P < Expr > > {
21
23
let parser = rustc_parse:: unwrap_or_emit_fatal ( rustc_parse:: new_parser_from_source_str (
@@ -46,4 +48,36 @@ impl MutVisitor for Normalize {
46
48
fn visit_span ( & mut self , span : & mut Span ) {
47
49
* span = DUMMY_SP ;
48
50
}
51
+
52
+ fn visit_attribute ( & mut self , attr : & mut Attribute ) {
53
+ attr. id = AttrId :: from_u32 ( 0 ) ;
54
+ if let AttrKind :: Normal ( normal_attr) = & mut attr. kind {
55
+ if let Some ( tokens) = & mut normal_attr. tokens {
56
+ let mut stream = tokens. to_attr_token_stream ( ) ;
57
+ normalize_attr_token_stream ( & mut stream) ;
58
+ * tokens = LazyAttrTokenStream :: new_direct ( stream) ;
59
+ }
60
+ }
61
+ mut_visit:: walk_attribute ( self , attr) ;
62
+ }
63
+ }
64
+
65
+ fn normalize_attr_token_stream ( stream : & mut AttrTokenStream ) {
66
+ Arc :: make_mut ( & mut stream. 0 )
67
+ . iter_mut ( )
68
+ . for_each ( normalize_attr_token_tree) ;
69
+ }
70
+
71
+ fn normalize_attr_token_tree ( token : & mut AttrTokenTree ) {
72
+ match token {
73
+ AttrTokenTree :: Token ( token, _spacing) => {
74
+ Normalize . visit_span ( & mut token. span ) ;
75
+ }
76
+ AttrTokenTree :: Delimited ( dspan, _spacing, _delim, stream) => {
77
+ normalize_attr_token_stream ( stream) ;
78
+ Normalize . visit_span ( & mut dspan. open ) ;
79
+ Normalize . visit_span ( & mut dspan. close ) ;
80
+ }
81
+ AttrTokenTree :: AttrsTarget ( _) => unimplemented ! ( "AttrTokenTree::AttrsTarget" ) ,
82
+ }
49
83
}
0 commit comments