cargo/core/compiler/
unit_graph.rs
1use crate::core::compiler::Unit;
6use crate::core::compiler::{CompileKind, CompileMode};
7use crate::core::profiles::{Profile, UnitFor};
8use crate::core::{PackageId, Target};
9use crate::util::interning::InternedString;
10use crate::util::CargoResult;
11use crate::GlobalContext;
12use std::collections::HashMap;
13
14pub type UnitGraph = HashMap<Unit, Vec<UnitDep>>;
16
17#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
19pub struct UnitDep {
20 pub unit: Unit,
22 pub unit_for: UnitFor,
25 pub extern_crate_name: InternedString,
27 pub dep_name: Option<InternedString>,
33 pub public: bool,
35 pub noprelude: bool,
37}
38
39const VERSION: u32 = 1;
40
41#[derive(serde::Serialize)]
42struct SerializedUnitGraph<'a> {
43 version: u32,
44 units: Vec<SerializedUnit<'a>>,
45 roots: Vec<usize>,
46}
47
48#[derive(serde::Serialize)]
49struct SerializedUnit<'a> {
50 pkg_id: PackageId,
51 target: &'a Target,
52 profile: &'a Profile,
53 platform: CompileKind,
54 mode: CompileMode,
55 features: &'a Vec<InternedString>,
56 #[serde(skip_serializing_if = "std::ops::Not::not")] is_std: bool,
58 dependencies: Vec<SerializedUnitDep>,
59}
60
61#[derive(serde::Serialize)]
62struct SerializedUnitDep {
63 index: usize,
64 extern_crate_name: InternedString,
65 #[serde(skip_serializing_if = "Option::is_none")]
67 public: Option<bool>,
68 #[serde(skip_serializing_if = "Option::is_none")]
70 noprelude: Option<bool>,
71 }
74
75pub fn emit_serialized_unit_graph(
78 root_units: &[Unit],
79 unit_graph: &UnitGraph,
80 gctx: &GlobalContext,
81) -> CargoResult<()> {
82 let mut units: Vec<(&Unit, &Vec<UnitDep>)> = unit_graph.iter().collect();
83 units.sort_unstable();
84 let indices: HashMap<&Unit, usize> = units
86 .iter()
87 .enumerate()
88 .map(|(i, val)| (val.0, i))
89 .collect();
90 let roots = root_units.iter().map(|root| indices[root]).collect();
91 let ser_units = units
92 .iter()
93 .map(|(unit, unit_deps)| {
94 let dependencies = unit_deps
95 .iter()
96 .map(|unit_dep| {
97 let (public, noprelude) = if gctx.nightly_features_allowed {
99 (Some(unit_dep.public), Some(unit_dep.noprelude))
100 } else {
101 (None, None)
102 };
103 SerializedUnitDep {
104 index: indices[&unit_dep.unit],
105 extern_crate_name: unit_dep.extern_crate_name,
106 public,
107 noprelude,
108 }
109 })
110 .collect();
111 SerializedUnit {
112 pkg_id: unit.pkg.package_id(),
113 target: &unit.target,
114 profile: &unit.profile,
115 platform: unit.kind,
116 mode: unit.mode,
117 features: &unit.features,
118 is_std: unit.is_std,
119 dependencies,
120 }
121 })
122 .collect();
123
124 gctx.shell().print_json(&SerializedUnitGraph {
125 version: VERSION,
126 units: ser_units,
127 roots,
128 })
129}