rustc_passes/
debugger_visualizer.rs1use rustc_ast::ast::NodeId;
4use rustc_ast::{HasNodeId, ItemKind, ast};
5use rustc_attr_parsing::AttributeParser;
6use rustc_expand::base::resolve_path;
7use rustc_hir::Attribute;
8use rustc_hir::attrs::{AttributeKind, DebugVisualizer};
9use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
10use rustc_middle::query::{LocalCrate, Providers};
11use rustc_middle::ty::TyCtxt;
12use rustc_session::Session;
13use rustc_span::{DUMMY_SP, Span, sym};
14
15use crate::errors::DebugVisualizerUnreadable;
16
17impl DebuggerVisualizerCollector<'_> {
18 fn check_for_debugger_visualizer(
19 &mut self,
20 attrs: &[ast::Attribute],
21 span: Span,
22 node_id: NodeId,
23 ) {
24 if let Some(Attribute::Parsed(AttributeKind::DebuggerVisualizer(visualizers))) =
25 AttributeParser::parse_limited(
26 &self.sess,
27 attrs,
28 sym::debugger_visualizer,
29 span,
30 node_id,
31 None,
32 )
33 {
34 for DebugVisualizer { span, visualizer_type, path } in visualizers {
35 let file = match resolve_path(&self.sess, path.as_str(), span) {
36 Ok(file) => file,
37 Err(err) => {
38 err.emit();
39 return;
40 }
41 };
42
43 match self.sess.source_map().load_binary_file(&file) {
44 Ok((source, _)) => {
45 self.visualizers.push(DebuggerVisualizerFile::new(
46 source,
47 visualizer_type,
48 file,
49 ));
50 }
51 Err(error) => {
52 self.sess.dcx().emit_err(DebugVisualizerUnreadable {
53 span,
54 file: &file,
55 error,
56 });
57 }
58 }
59 }
60 }
61 }
62}
63
64struct DebuggerVisualizerCollector<'a> {
65 sess: &'a Session,
66 visualizers: Vec<DebuggerVisualizerFile>,
67}
68
69impl<'ast> rustc_ast::visit::Visitor<'ast> for DebuggerVisualizerCollector<'_> {
70 fn visit_item(&mut self, item: &'ast rustc_ast::Item) -> Self::Result {
71 if let ItemKind::Mod(..) = item.kind {
72 self.check_for_debugger_visualizer(&item.attrs, item.span, item.node_id());
73 }
74 rustc_ast::visit::walk_item(self, item);
75 }
76 fn visit_crate(&mut self, krate: &'ast ast::Crate) -> Self::Result {
77 self.check_for_debugger_visualizer(&krate.attrs, DUMMY_SP, krate.id);
78 rustc_ast::visit::walk_crate(self, krate);
79 }
80}
81
82fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec<DebuggerVisualizerFile> {
84 let resolver_and_krate = tcx.resolver_for_lowering().borrow();
85 let krate = &*resolver_and_krate.1;
86
87 let mut visitor = DebuggerVisualizerCollector { sess: tcx.sess, visualizers: Vec::new() };
88 rustc_ast::visit::Visitor::visit_crate(&mut visitor, krate);
89
90 visitor.visualizers
94}
95
96pub(crate) fn provide(providers: &mut Providers) {
97 providers.debugger_visualizers = debugger_visualizers;
98}