|
| 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