|  | 
|  | 1 | +use rustc_hir::attrs::{DebugVisualizer, DebuggerVisualizerType}; | 
|  | 2 | + | 
|  | 3 | +use super::prelude::*; | 
|  | 4 | + | 
|  | 5 | +pub(crate) struct DebuggerViualizerParser; | 
|  | 6 | + | 
|  | 7 | +impl<S: Stage> CombineAttributeParser<S> for DebuggerViualizerParser { | 
|  | 8 | +    const PATH: &[Symbol] = &[sym::debugger_visualizer]; | 
|  | 9 | +    const ALLOWED_TARGETS: AllowedTargets = | 
|  | 10 | +        AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]); | 
|  | 11 | +    const TEMPLATE: AttributeTemplate = template!( | 
|  | 12 | +        List: &[r#"natvis_file = "...", gdb_script_file = "...""#], | 
|  | 13 | +        "https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute" | 
|  | 14 | +    ); | 
|  | 15 | + | 
|  | 16 | +    type Item = DebugVisualizer; | 
|  | 17 | +    const CONVERT: ConvertFn<Self::Item> = |v, _| AttributeKind::DebuggerVisualizer(v); | 
|  | 18 | + | 
|  | 19 | +    fn extend<'c>( | 
|  | 20 | +        cx: &'c mut AcceptContext<'_, '_, S>, | 
|  | 21 | +        args: &'c ArgParser<'_>, | 
|  | 22 | +    ) -> impl IntoIterator<Item = Self::Item> + 'c { | 
|  | 23 | +        let Some(l) = args.list() else { | 
|  | 24 | +            cx.expected_list(args.span().unwrap_or(cx.attr_span)); | 
|  | 25 | +            return None; | 
|  | 26 | +        }; | 
|  | 27 | +        let Some(single) = l.single() else { | 
|  | 28 | +            cx.expected_single_argument(l.span); | 
|  | 29 | +            return None; | 
|  | 30 | +        }; | 
|  | 31 | +        let Some(mi) = single.meta_item() else { | 
|  | 32 | +            cx.expected_name_value(single.span(), None); | 
|  | 33 | +            return None; | 
|  | 34 | +        }; | 
|  | 35 | +        let path = mi.path().word_sym(); | 
|  | 36 | +        let visualizer_type = match path { | 
|  | 37 | +            Some(sym::natvis_file) => DebuggerVisualizerType::Natvis, | 
|  | 38 | +            Some(sym::gdb_script_file) => DebuggerVisualizerType::GdbPrettyPrinter, | 
|  | 39 | +            _ => { | 
|  | 40 | +                cx.expected_specific_argument( | 
|  | 41 | +                    mi.path().span(), | 
|  | 42 | +                    &[sym::natvis_file, sym::gdb_script_file], | 
|  | 43 | +                ); | 
|  | 44 | +                return None; | 
|  | 45 | +            } | 
|  | 46 | +        }; | 
|  | 47 | + | 
|  | 48 | +        let Some(path) = mi.args().name_value() else { | 
|  | 49 | +            cx.expected_name_value(single.span(), path); | 
|  | 50 | +            return None; | 
|  | 51 | +        }; | 
|  | 52 | + | 
|  | 53 | +        let Some(path) = path.value_as_str() else { | 
|  | 54 | +            cx.expected_string_literal(path.value_span, Some(path.value_as_lit())); | 
|  | 55 | +            return None; | 
|  | 56 | +        }; | 
|  | 57 | + | 
|  | 58 | +        Some(DebugVisualizer { span: mi.span(), visualizer_type, path }) | 
|  | 59 | +    } | 
|  | 60 | +} | 
0 commit comments