@@ -25,7 +25,9 @@ use ra_ap_syntax::{
2525#[ macro_export]
2626macro_rules! pre_emit {
2727 ( Item , $self: ident, $node: ident) => {
28- $self. setup_item_expansion( $node) ;
28+ if let Some ( label) = $self. prepare_item_expansion( $node) {
29+ return Some ( label) ;
30+ }
2931 } ;
3032 ( $( $_: tt) * ) => { } ;
3133}
@@ -687,6 +689,9 @@ impl<'a> Translator<'a> {
687689 {
688690 return true ;
689691 }
692+ if syntax. kind ( ) == SyntaxKind :: TOKEN_TREE {
693+ return true ;
694+ }
690695 }
691696 false
692697 }
@@ -723,48 +728,75 @@ impl<'a> Translator<'a> {
723728 }
724729 }
725730
726- pub ( crate ) fn setup_item_expansion ( & mut self , node : & ast:: Item ) {
727- if self . semantics . is_some_and ( |s| {
728- let file = s. hir_file_for ( node. syntax ( ) ) ;
729- let node = InFile :: new ( file, node) ;
730- s. is_attr_macro_call ( node)
731- } ) {
731+ pub ( crate ) fn prepare_item_expansion (
732+ & mut self ,
733+ node : & ast:: Item ,
734+ ) -> Option < Label < generated:: Item > > {
735+ if self . source_kind == SourceKind :: Library {
736+ // if the item expands via an attribute macro, we want to only emit the expansion
737+ if let Some ( expanded) = self . emit_attribute_macro_expansion ( node) {
738+ // we wrap it in a dummy MacroCall to get a single Item label that can replace
739+ // the original Item
740+ let label = self . trap . emit ( generated:: MacroCall {
741+ id : TrapId :: Star ,
742+ attrs : vec ! [ ] ,
743+ path : None ,
744+ token_tree : None ,
745+ } ) ;
746+ generated:: MacroCall :: emit_macro_call_expansion (
747+ label,
748+ expanded. into ( ) ,
749+ & mut self . trap . writer ,
750+ ) ;
751+ return Some ( label. into ( ) ) ;
752+ }
753+ }
754+ let semantics = self . semantics . as_ref ( ) ?;
755+ let file = semantics. hir_file_for ( node. syntax ( ) ) ;
756+ let node = InFile :: new ( file, node) ;
757+ if semantics. is_attr_macro_call ( node) {
732758 self . macro_context_depth += 1 ;
733759 }
760+ None
761+ }
762+
763+ fn emit_attribute_macro_expansion (
764+ & mut self ,
765+ node : & ast:: Item ,
766+ ) -> Option < Label < generated:: MacroItems > > {
767+ let semantics = self . semantics ?;
768+ let file = semantics. hir_file_for ( node. syntax ( ) ) ;
769+ let infile_node = InFile :: new ( file, node) ;
770+ if !semantics. is_attr_macro_call ( infile_node) {
771+ return None ;
772+ }
773+ self . macro_context_depth -= 1 ;
774+ if self . macro_context_depth > 0 {
775+ // only expand the outermost attribute macro
776+ return None ;
777+ }
778+ let ExpandResult {
779+ value : expanded, ..
780+ } = semantics. expand_attr_macro ( node) ?;
781+ self . emit_macro_expansion_parse_errors ( node, & expanded) ;
782+ let macro_items = ast:: MacroItems :: cast ( expanded) . or_else ( || {
783+ let message = "attribute macro expansion cannot be cast to MacroItems" . to_owned ( ) ;
784+ let location = self . location_for_node ( node) ;
785+ self . emit_diagnostic (
786+ DiagnosticSeverity :: Warning ,
787+ "item_expansion" . to_owned ( ) ,
788+ message. clone ( ) ,
789+ message,
790+ location. unwrap_or ( UNKNOWN_LOCATION ) ,
791+ ) ;
792+ None
793+ } ) ?;
794+ self . emit_macro_items ( & macro_items)
734795 }
735796
736797 pub ( crate ) fn emit_item_expansion ( & mut self , node : & ast:: Item , label : Label < generated:: Item > ) {
737- ( || {
738- let semantics = self . semantics ?;
739- let file = semantics. hir_file_for ( node. syntax ( ) ) ;
740- let infile_node = InFile :: new ( file, node) ;
741- if !semantics. is_attr_macro_call ( infile_node) {
742- return None ;
743- }
744- self . macro_context_depth -= 1 ;
745- if self . macro_context_depth > 0 {
746- // only expand the outermost attribute macro
747- return None ;
748- }
749- let ExpandResult {
750- value : expanded, ..
751- } = semantics. expand_attr_macro ( node) ?;
752- self . emit_macro_expansion_parse_errors ( node, & expanded) ;
753- let macro_items = ast:: MacroItems :: cast ( expanded) . or_else ( || {
754- let message = "attribute macro expansion cannot be cast to MacroItems" . to_owned ( ) ;
755- let location = self . location_for_node ( node) ;
756- self . emit_diagnostic (
757- DiagnosticSeverity :: Warning ,
758- "item_expansion" . to_owned ( ) ,
759- message. clone ( ) ,
760- message,
761- location. unwrap_or ( UNKNOWN_LOCATION ) ,
762- ) ;
763- None
764- } ) ?;
765- let expanded = self . emit_macro_items ( & macro_items) ?;
798+ if let Some ( expanded) = self . emit_attribute_macro_expansion ( node) {
766799 generated:: Item :: emit_attribute_macro_expansion ( label, expanded, & mut self . trap . writer ) ;
767- Some ( ( ) )
768- } ) ( ) ;
800+ }
769801 }
770802}
0 commit comments