@@ -6,13 +6,15 @@ use codeql_extractor::trap::{self};
66use log:: Level ;
77use ra_ap_hir:: db:: ExpandDatabase ;
88use ra_ap_hir:: Semantics ;
9+ use ra_ap_hir_expand:: ExpandTo ;
910use ra_ap_ide_db:: line_index:: { LineCol , LineIndex } ;
1011use ra_ap_ide_db:: RootDatabase ;
1112use ra_ap_parser:: SyntaxKind ;
1213use ra_ap_span:: { EditionedFileId , TextSize } ;
1314use ra_ap_syntax:: ast:: RangeItem ;
1415use ra_ap_syntax:: {
15- ast, AstNode , NodeOrToken , SyntaxElementChildren , SyntaxError , SyntaxToken , TextRange ,
16+ ast, AstNode , NodeOrToken , SyntaxElementChildren , SyntaxError , SyntaxNode , SyntaxToken ,
17+ TextRange ,
1618} ;
1719
1820#[ macro_export]
@@ -80,7 +82,7 @@ pub struct Translator<'a> {
8082 label : trap:: Label ,
8183 line_index : LineIndex ,
8284 file_id : Option < EditionedFileId > ,
83- pub semi : Option < Semantics < ' a , RootDatabase > > ,
85+ pub semantics : Option < Semantics < ' a , RootDatabase > > ,
8486}
8587
8688impl < ' a > Translator < ' a > {
@@ -90,15 +92,15 @@ impl<'a> Translator<'a> {
9092 label : trap:: Label ,
9193 line_index : LineIndex ,
9294 file_id : Option < EditionedFileId > ,
93- semi : Option < Semantics < ' a , RootDatabase > > ,
95+ semantics : Option < Semantics < ' a , RootDatabase > > ,
9496 ) -> Translator < ' a > {
9597 Translator {
9698 trap,
9799 path,
98100 label,
99101 line_index,
100102 file_id,
101- semi ,
103+ semantics ,
102104 }
103105 }
104106 fn location ( & self , range : TextRange ) -> ( LineCol , LineCol ) {
@@ -122,8 +124,8 @@ impl<'a> Translator<'a> {
122124 }
123125
124126 pub fn text_range_for_node ( & mut self , node : & impl ast:: AstNode ) -> Option < TextRange > {
125- if let Some ( semi ) = self . semi . as_ref ( ) {
126- let file_range = semi . original_range ( node. syntax ( ) ) ;
127+ if let Some ( semantics ) = self . semantics . as_ref ( ) {
128+ let file_range = semantics . original_range ( node. syntax ( ) ) ;
127129 let file_id = self . file_id ?;
128130 if file_id == file_range. file_id {
129131 Some ( file_range. range )
@@ -235,86 +237,95 @@ impl<'a> Translator<'a> {
235237 }
236238 }
237239 }
240+ fn emit_macro_expansion_parse_errors ( & mut self , mcall : & ast:: MacroCall , expanded : & SyntaxNode ) {
241+ let semantics = self . semantics . as_ref ( ) . unwrap ( ) ;
242+ if let Some ( value) = semantics
243+ . hir_file_for ( expanded)
244+ . macro_file ( )
245+ . and_then ( |macro_file| {
246+ semantics
247+ . db
248+ . parse_macro_expansion_error ( macro_file. macro_call_id )
249+ } )
250+ {
251+ if let Some ( err) = & value. err {
252+ let ( message, _error) = err. render_to_string ( semantics. db ) ;
253+
254+ if err. span ( ) . anchor . file_id == semantics. hir_file_for ( mcall. syntax ( ) ) {
255+ let location = err. span ( ) . range
256+ + semantics
257+ . db
258+ . ast_id_map ( err. span ( ) . anchor . file_id . into ( ) )
259+ . get_erased ( err. span ( ) . anchor . ast_id )
260+ . text_range ( )
261+ . start ( ) ;
262+ self . emit_parse_error ( mcall, & SyntaxError :: new ( message, location) ) ;
263+ } ;
264+ }
265+ for err in value. value . iter ( ) {
266+ self . emit_parse_error ( mcall, err) ;
267+ }
268+ }
269+ }
270+
271+ fn emit_expanded_as (
272+ & mut self ,
273+ expand_to : ExpandTo ,
274+ expanded : SyntaxNode ,
275+ ) -> Option < Label < generated:: AstNode > > {
276+ match expand_to {
277+ ra_ap_hir_expand:: ExpandTo :: Statements => {
278+ ast:: MacroStmts :: cast ( expanded) . map ( |x| self . emit_macro_stmts ( x) . into ( ) )
279+ }
280+ ra_ap_hir_expand:: ExpandTo :: Items => {
281+ ast:: MacroItems :: cast ( expanded) . map ( |x| self . emit_macro_items ( x) . into ( ) )
282+ }
283+
284+ ra_ap_hir_expand:: ExpandTo :: Pattern => {
285+ ast:: Pat :: cast ( expanded) . map ( |x| self . emit_pat ( x) . into ( ) )
286+ }
287+ ra_ap_hir_expand:: ExpandTo :: Type => {
288+ ast:: Type :: cast ( expanded) . map ( |x| self . emit_type ( x) . into ( ) )
289+ }
290+ ra_ap_hir_expand:: ExpandTo :: Expr => {
291+ ast:: Expr :: cast ( expanded) . map ( |x| self . emit_expr ( x) . into ( ) )
292+ }
293+ }
294+ }
238295 pub ( crate ) fn extract_macro_call_expanded (
239296 & mut self ,
240297 mcall : & ast:: MacroCall ,
241298 label : Label < generated:: MacroCall > ,
242299 ) {
243- if let Some ( semi) = & self . semi {
244- if let Some ( expanded) = semi. expand ( mcall) {
245- if let Some ( value) =
246- semi. hir_file_for ( & expanded)
247- . macro_file ( )
248- . and_then ( |macro_file| {
249- semi. db
250- . parse_macro_expansion_error ( macro_file. macro_call_id )
251- } )
252- {
253- if let Some ( err) = & value. err {
254- let ( message, _error) = err. render_to_string ( semi. db ) ;
255-
256- if err. span ( ) . anchor . file_id == semi. hir_file_for ( mcall. syntax ( ) ) {
257- let location = err. span ( ) . range
258- + semi
259- . db
260- . ast_id_map ( err. span ( ) . anchor . file_id . into ( ) )
261- . get_erased ( err. span ( ) . anchor . ast_id )
262- . text_range ( )
263- . start ( ) ;
264- self . emit_parse_error ( mcall, & SyntaxError :: new ( message, location) ) ;
265- } ;
266- }
267- for err in value. value . iter ( ) {
268- self . emit_parse_error ( mcall, err) ;
269- }
270- }
271- let expand_to = ra_ap_hir_expand:: ExpandTo :: from_call_site ( mcall) ;
272- let kind = expanded. kind ( ) ;
273- let value: Option < Label < crate :: generated:: AstNode > > = match expand_to {
274- ra_ap_hir_expand:: ExpandTo :: Statements => {
275- ast:: MacroStmts :: cast ( expanded) . map ( |x| self . emit_macro_stmts ( x) . into ( ) )
276- }
277- ra_ap_hir_expand:: ExpandTo :: Items => {
278- ast:: MacroItems :: cast ( expanded) . map ( |x| self . emit_macro_items ( x) . into ( ) )
279- }
280-
281- ra_ap_hir_expand:: ExpandTo :: Pattern => {
282- ast:: Pat :: cast ( expanded) . map ( |x| self . emit_pat ( x) . into ( ) )
283- }
284- ra_ap_hir_expand:: ExpandTo :: Type => {
285- ast:: Type :: cast ( expanded) . map ( |x| self . emit_type ( x) . into ( ) )
286- }
287- ra_ap_hir_expand:: ExpandTo :: Expr => {
288- ast:: Expr :: cast ( expanded) . map ( |x| self . emit_expr ( x) . into ( ) )
289- }
290- } ;
291- if let Some ( value) = value {
292- MacroCall :: emit_expanded ( label, value, & mut self . trap . writer ) ;
293- } else {
294- let range = self . text_range_for_node ( mcall) ;
295- self . emit_parse_error ( mcall, & SyntaxError :: new (
300+ if let Some ( expanded) = self . semantics . as_ref ( ) . and_then ( |s| s. expand ( mcall) ) {
301+ self . emit_macro_expansion_parse_errors ( mcall, & expanded) ;
302+ let expand_to = ra_ap_hir_expand:: ExpandTo :: from_call_site ( mcall) ;
303+ let kind = expanded. kind ( ) ;
304+ if let Some ( value) = self . emit_expanded_as ( expand_to, expanded) {
305+ MacroCall :: emit_expanded ( label, value, & mut self . trap . writer ) ;
306+ } else {
307+ let range = self . text_range_for_node ( mcall) ;
308+ self . emit_parse_error ( mcall, & SyntaxError :: new (
296309 format ! (
297310 "macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected" ,
298311 mcall. path( ) . map( |p| p. to_string( ) ) . unwrap_or_default( ) ,
299312 kind, expand_to
300313 ) ,
301314 range. unwrap_or_else ( || TextRange :: empty ( TextSize :: from ( 0 ) ) ) ,
302315 ) ) ;
303- }
304- } else {
305- let range = self . text_range_for_node ( mcall) ;
306-
307- self . emit_parse_error (
308- mcall,
309- & SyntaxError :: new (
310- format ! (
311- "macro expansion failed: could not resolve macro '{}'" ,
312- mcall. path( ) . map( |p| p. to_string( ) ) . unwrap_or_default( )
313- ) ,
314- range. unwrap_or_else ( || TextRange :: empty ( TextSize :: from ( 0 ) ) ) ,
315- ) ,
316- ) ;
317316 }
317+ } else {
318+ let range = self . text_range_for_node ( mcall) ;
319+ self . emit_parse_error (
320+ mcall,
321+ & SyntaxError :: new (
322+ format ! (
323+ "macro expansion failed: could not resolve macro '{}'" ,
324+ mcall. path( ) . map( |p| p. to_string( ) ) . unwrap_or_default( )
325+ ) ,
326+ range. unwrap_or_else ( || TextRange :: empty ( TextSize :: from ( 0 ) ) ) ,
327+ ) ,
328+ ) ;
318329 }
319330 }
320331}
0 commit comments