Skip to content

Commit a81004a

Browse files
authored
Merge pull request #12 from darsor/dev/self-contained-use
Self-contained use statements, fixes #9
2 parents a68645c + 425cba6 commit a81004a

10 files changed

Lines changed: 67 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [unreleased]
99

10+
### Fixed
11+
12+
- Generate self-contained `use` statements that don't rely on the module structure outside the generated code. ([#9](https://github.com/darsor/PeakRDL-rust/issues/9))
13+
1014
## [0.7.1] - 2026-03-23
1115

1216
### Fixed

src/peakrdl_rust/component_context.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ def enter_addrmap_or_regfile_or_memory(
305305
else:
306306
module_names = utils.crate_module_path(child)
307307
scoped_module = "::".join(
308-
["crate", "components"] + list(map(kw_filter, module_names))
308+
["_root", "components"] + list(map(kw_filter, module_names))
309309
)
310310
named_type_instances.append((inst_name, scoped_module))
311311

@@ -527,7 +527,7 @@ def enter_Field(self, node: FieldNode) -> Optional[WalkerAction]:
527527
instantiating_file = self.get_node_module_file(instantiating_node)
528528
assert instantiating_file in self.components
529529
scoped_module = "::".join(
530-
["crate", "components"] + list(map(kw_filter, module_names))
530+
["_root", "components"] + list(map(kw_filter, module_names))
531531
)
532532
self.components[instantiating_file].named_type_instances.append(
533533
(snakecase(field.inst_name), scoped_module)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! SystemRDL component definitions
22
#![allow(non_camel_case_types)] // needed for type normalization suffixes
33

4+
use super::_root; // alias to root module of generated code
5+
46
{% for component in ctx.components %}
57
pub mod {{component|kw_filter}};
68
{% endfor %}

src/peakrdl_rust/templates/components/macros.jinja2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ while {{idx}} < {{dims[depth]}} {
1212
{%- endmacro -%}
1313

1414
{% macro includes(ctx) %}
15+
#[allow(unused_imports)]
16+
use super::_root; // alias to root module of generated code
1517
{% for use in ctx.use_statements %}
1618
{{use}}
1719
{% endfor %}
@@ -26,6 +28,8 @@ pub mod {{mod|kw_filter}};
2628
{% if ctx.named_type_declarations|length > 0 %}
2729
/// Named types defined within this component's body
2830
pub mod named_types {
31+
#[allow(unused_imports)]
32+
use super::_root; // alias to root module of generated code
2933
{% for mod in ctx.named_type_declarations %}
3034
pub mod {{mod|kw_filter}};
3135
{% endfor %}

src/peakrdl_rust/templates/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ pub mod components;
1616
pub use {{top_node}};
1717
{% endfor %}
1818

19+
/// Alias this module as the root of the generated code
20+
mod _root {
21+
#[allow(unused_imports)]
22+
pub use super::*;
23+
}
24+
1925
/// Version of PeakRDL-rust used to generate this code
2026
pub const PEAKRDL_RUST_VERSION: &str = "{{ctx.peakrdl_rust_version}}";
2127

tests/rdl_src/non_root_module.rdl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
reg r_global {
2+
field {} f1[4];
3+
4+
field myfield {};
5+
myfield f2;
6+
myfield f3[4];
7+
field myfield2 {fieldwidth = 4;};
8+
myfield2 f4;
9+
};
10+
11+
regfile rf_global #(
12+
longint unsigned NUM = 4
13+
){
14+
reg r_local {
15+
field {} f_param[NUM];
16+
field myfield {};
17+
myfield f_param2[NUM];
18+
} r1;
19+
r_global r2;
20+
21+
signal {} xyz;
22+
};
23+
24+
addrmap top {
25+
rf_global rf1;
26+
rf_global #(.NUM (8)) rf2;
27+
rf_global rf3[4] @ 0x1000 += 0x100;
28+
rf_global rf4[4] @ 0x2000 += 0x200;
29+
};

tests/templates/lib.rs.jinja2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub mod generated;
2+
{% if ctx.test_name != "non_root_module" %}
3+
pub use generated::*;
4+
{% endif %}

tests/templates/lib.rs.tmpl

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/test_peakrdl_rust.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from pathlib import Path
66
from typing import TYPE_CHECKING
77

8+
import jinja2 as jj
89
import pytest
910
from systemrdl.compiler import RDLCompiler
1011

@@ -71,11 +72,22 @@ def do_export(rdl_file: Path) -> Path:
7172
(crate_dir / "tests").mkdir(exist_ok=True)
7273
shutil.copyfile(integration_test, crate_dir / "tests" / integration_test.name)
7374

74-
# copy boilerplate templates
75+
# render boilerplate templates
7576
templates_dir = Path(__file__).parent / "templates"
76-
print(f"copied to {crate_dir / 'Cargo.toml'}")
77-
shutil.copyfile(templates_dir / "Cargo.toml.tmpl", crate_dir / "Cargo.toml")
78-
shutil.copyfile(templates_dir / "lib.rs.tmpl", src_dir / "lib.rs")
77+
loader = jj.FileSystemLoader(templates_dir.resolve())
78+
jj_env = jj.Environment(
79+
loader=loader,
80+
undefined=jj.StrictUndefined,
81+
trim_blocks=True,
82+
lstrip_blocks=True,
83+
)
84+
context = {
85+
"test_name": rdl_file.stem,
86+
}
87+
with open(crate_dir / "Cargo.toml", "w") as f:
88+
jj_env.get_template("Cargo.toml.jinja2").stream(ctx=context).dump(f) # type: ignore # jinja incorrectly typed
89+
with open(src_dir / "lib.rs", "w") as f:
90+
jj_env.get_template("lib.rs.jinja2").stream(ctx=context).dump(f) # type: ignore # jinja incorrectly typed
7991

8092
return crate_dir
8193

0 commit comments

Comments
 (0)