Skip to content

Commit fd6fa0a

Browse files
committed
add GeneratorContext.scope_map to avoid need to pass around parent_node_id
1 parent e65b888 commit fd6fa0a

File tree

2 files changed

+40
-34
lines changed

2 files changed

+40
-34
lines changed

capnpc/src/codegen.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl CodeGenerationCommand {
111111
Line("// DO NOT EDIT.".to_string()),
112112
Line(format!("// source: {}", requested_file.get_filename()?)),
113113
BlankLine,
114-
generate_node(&gen, id, &root_name, None)?,
114+
generate_node(&gen, id, &root_name)?,
115115
]);
116116

117117
let text = stringify(&lines);
@@ -160,6 +160,11 @@ pub struct GeneratorContext<'a> {
160160
pub request: schema_capnp::code_generator_request::Reader<'a>,
161161
pub node_map: collections::hash_map::HashMap<u64, schema_capnp::node::Reader<'a>>,
162162
pub scope_map: collections::hash_map::HashMap<u64, Vec<String>>,
163+
164+
/// Map from node ID to the node ID of its parent scope. This is equal to node.scope_id
165+
/// for all nodes except for autogenerated interface Param and Result structs;
166+
/// those have scope_id set to 0. See the comment on paramStructType in schema.capnp.
167+
pub node_parents: collections::hash_map::HashMap<u64, u64>,
163168
}
164169

165170
impl<'a> GeneratorContext<'a> {
@@ -180,10 +185,28 @@ impl<'a> GeneratorContext<'a> {
180185
request: message.get_root()?,
181186
node_map: collections::hash_map::HashMap::<u64, schema_capnp::node::Reader<'a>>::new(),
182187
scope_map: collections::hash_map::HashMap::<u64, Vec<String>>::new(),
188+
node_parents: collections::hash_map::HashMap::new(),
183189
};
184190

185191
for node in gen.request.get_nodes()? {
186192
gen.node_map.insert(node.get_id(), node);
193+
gen.node_parents.insert(node.get_id(), node.get_scope_id());
194+
}
195+
196+
// Fix up "anonymous" method params and results scopes.
197+
for node in gen.request.get_nodes()? {
198+
if let Ok(schema_capnp::node::Interface(interface_reader)) = node.which() {
199+
for method in interface_reader.get_methods()? {
200+
let param_struct_type = method.get_param_struct_type();
201+
if gen.node_parents.get(&param_struct_type) == Some(&0) {
202+
gen.node_parents.insert(param_struct_type, node.get_id());
203+
}
204+
let result_struct_type = method.get_result_struct_type();
205+
if gen.node_parents.get(&result_struct_type) == Some(&0) {
206+
gen.node_parents.insert(result_struct_type, node.get_id());
207+
}
208+
}
209+
}
187210
}
188211

189212
for requested_file in gen.request.get_requested_files()? {
@@ -291,6 +314,7 @@ impl<'a> GeneratorContext<'a> {
291314
}
292315
}
293316
}
317+
294318
Ok(())
295319
}
296320

@@ -1527,9 +1551,6 @@ fn generate_node(
15271551
gen: &GeneratorContext,
15281552
node_id: u64,
15291553
node_name: &str,
1530-
// Ugh. We need this to deal with the anonymous Params and Results
1531-
// structs that go with RPC methods.
1532-
parent_node_id: Option<u64>,
15331554
) -> ::capnp::Result<FormattedText> {
15341555
use crate::schema_capnp::*;
15351556

@@ -1540,15 +1561,15 @@ fn generate_node(
15401561
let nested_nodes = node_reader.get_nested_nodes()?;
15411562
for nested_node in nested_nodes {
15421563
let id = nested_node.get_id();
1543-
nested_output.push(generate_node(gen, id, gen.get_last_name(id)?, None)?);
1564+
nested_output.push(generate_node(gen, id, gen.get_last_name(id)?)?);
15441565
}
15451566

15461567
match node_reader.which()? {
15471568
node::File(()) => {
15481569
output.push(Branch(nested_output));
15491570
}
15501571
node::Struct(struct_reader) => {
1551-
let params = node_reader.parameters_texts(gen, parent_node_id);
1572+
let params = node_reader.parameters_texts(gen);
15521573
output.push(BlankLine);
15531574

15541575
let is_generic = node_reader.get_is_generic();
@@ -1634,7 +1655,7 @@ fn generate_node(
16341655

16351656
if let Ok(field::Group(group)) = field.which() {
16361657
let id = group.get_type_id();
1637-
let text = generate_node(gen, id, gen.get_last_name(id)?, None)?;
1658+
let text = generate_node(gen, id, gen.get_last_name(id)?)?;
16381659
nested_output.push(text);
16391660
}
16401661
}
@@ -1968,7 +1989,7 @@ fn generate_node(
19681989
}
19691990

19701991
node::Interface(interface) => {
1971-
let params = node_reader.parameters_texts(gen, parent_node_id);
1992+
let params = node_reader.parameters_texts(gen);
19721993
output.push(BlankLine);
19731994

19741995
let is_generic = node_reader.get_is_generic();
@@ -2002,7 +2023,7 @@ fn generate_node(
20022023
let (param_scopes, params_ty_params) = if param_node.get_scope_id() == 0 {
20032024
let mut names = names.clone();
20042025
let local_name = module_name(&format!("{name}Params"));
2005-
nested_output.push(generate_node(gen, param_id, &local_name, Some(node_id))?);
2026+
nested_output.push(generate_node(gen, param_id, &local_name)?);
20062027
names.push(local_name);
20072028
(names, params.params.clone())
20082029
} else {
@@ -2025,7 +2046,7 @@ fn generate_node(
20252046
let (result_scopes, results_ty_params) = if result_node.get_scope_id() == 0 {
20262047
let mut names = names.clone();
20272048
let local_name = module_name(&format!("{name}Results"));
2028-
nested_output.push(generate_node(gen, result_id, &local_name, Some(node_id))?);
2049+
nested_output.push(generate_node(gen, result_id, &local_name)?);
20292050
names.push(local_name);
20302051
(names, params.params.clone())
20312052
} else {

capnpc/src/codegen_types.rs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,7 @@ pub struct TypeParameterTexts {
8888

8989
// this is a collection of helpers acting on a "Node" (most of them are Type definitions)
9090
pub trait RustNodeInfo {
91-
fn parameters_texts(
92-
&self,
93-
gen: &crate::codegen::GeneratorContext,
94-
parent_node_id: Option<u64>,
95-
) -> TypeParameterTexts;
91+
fn parameters_texts(&self, gen: &crate::codegen::GeneratorContext) -> TypeParameterTexts;
9692
}
9793

9894
// this is a collection of helpers acting on a "Type" (someplace where a Type is used, not defined)
@@ -104,13 +100,9 @@ pub trait RustTypeInfo {
104100
}
105101

106102
impl<'a> RustNodeInfo for node::Reader<'a> {
107-
fn parameters_texts(
108-
&self,
109-
gen: &crate::codegen::GeneratorContext,
110-
parent_node_id: Option<u64>,
111-
) -> TypeParameterTexts {
103+
fn parameters_texts(&self, gen: &crate::codegen::GeneratorContext) -> TypeParameterTexts {
112104
if self.get_is_generic() {
113-
let params = get_type_parameters(gen, self.get_id(), parent_node_id);
105+
let params = get_type_parameters(gen, self.get_id());
114106
let type_parameters = params
115107
.iter()
116108
.map(|param| param.to_string())
@@ -431,28 +423,21 @@ pub fn do_branding(
431423
arguments = arguments))
432424
}
433425

434-
pub fn get_type_parameters(
435-
gen: &GeneratorContext,
436-
node_id: u64,
437-
mut parent_scope_id: Option<u64>,
438-
) -> Vec<String> {
426+
pub fn get_type_parameters(gen: &GeneratorContext, node_id: u64) -> Vec<String> {
439427
let mut current_node_id = node_id;
440428
let mut accumulator: Vec<Vec<String>> = Vec::new();
441429
loop {
442-
let Some(current_node) = gen.node_map.get(&current_node_id) else {
443-
break
444-
};
430+
let current_node = gen.node_map[&current_node_id];
445431
let mut params = Vec::new();
446432
for param in current_node.get_parameters().unwrap() {
447433
params.push(param.get_name().unwrap().to_string());
448434
}
449435

450436
accumulator.push(params);
451-
current_node_id = current_node.get_scope_id();
452-
if let (0, Some(id)) = (current_node_id, parent_scope_id) {
453-
current_node_id = id
454-
}
455-
parent_scope_id = None; // Only consider on the first time around.
437+
current_node_id = match gen.node_parents.get(&current_node_id).copied() {
438+
Some(0) | None => break,
439+
Some(id) => id,
440+
};
456441
}
457442

458443
accumulator.reverse();

0 commit comments

Comments
 (0)