Skip to content

Add a #[boa_module] macro to automatically implement a Module#4277

Merged
hansl merged 7 commits intoboa-dev:mainfrom
hansl:module-proc-macro
Jun 13, 2025
Merged

Add a #[boa_module] macro to automatically implement a Module#4277
hansl merged 7 commits intoboa-dev:mainfrom
hansl:module-proc-macro

Conversation

@hansl
Copy link
Contributor

@hansl hansl commented Jun 9, 2025

This adds a pub(super) fn boa_module(context: &mut Context) -> JsResult<Module> function to the same module that builds the module from its content.

It understands the following:

  1. fn some_func(...) -> ... {} will be added as functions to the module.
  2. const SOME_CONST: ... = ... will be added as values. The type of the constant value must support impl Into<JsValue>.
  3. type SomeType = ... will be added as a class. The class will be exported using the SomeType name (with renaming support).

Two schemes of renaming are now supported, one for classes and one for regular imports. Use #[boa(rename_class = "...")] to select the one you want.

A PascalCase renaming is also added to allow for classes.

Simple tests added for everything.

This adds a `pub(super) fn boa_module(context: &mut Context) -> JsResult<Module>`
function to the same module that builds the module from its content.

It understands the following:

1. `fn some_func(...) -> ... {}` will be added as functions to the module.
2. `const SOME_CONST: ... = ...` will be added as values. The type of the
   constant value must support `impl Into<JsValue>`.
3. `type SomeType = ...` will be added as a class. The class will be
   exported using the `SomeType` name (with renaming support).

Two schemes of renaming are now supported, one for classes and one for
regular imports. Use `#[boa(rename_class = "...")]` to select the one
you want.

A PascalCase renaming is also added to allow for classes.

Simple tests added for everything.
@hansl hansl requested a review from a team June 9, 2025 02:38
@jedel1043
Copy link
Member

Hmmm, I think it's REALLY surprising to have common Rust syntax be what determines what gets exported in the module...

Can we add an #[export] attribute instead? IMO it should be a lot more readable and less surprising overall to be a bit more explicit in this case.

@codecov
Copy link

codecov bot commented Jun 9, 2025

Codecov Report

Attention: Patch coverage is 19.73244% with 240 lines in your changes missing coverage. Please review.

Project coverage is 52.85%. Comparing base (6ddc2b4) to head (bc9df0f).
Report is 428 commits behind head on main.

Files with missing lines Patch % Lines
core/macros/src/module.rs 0.00% 124 Missing ⚠️
core/macros/src/utils.rs 38.18% 68 Missing ⚠️
core/macros/src/class.rs 0.00% 41 Missing ⚠️
core/interop/tests/module.rs 78.57% 3 Missing ⚠️
core/engine/src/module/synthetic.rs 75.00% 2 Missing ⚠️
core/macros/src/lib.rs 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4277      +/-   ##
==========================================
+ Coverage   47.24%   52.85%   +5.60%     
==========================================
  Files         476      491      +15     
  Lines       46892    51078    +4186     
==========================================
+ Hits        22154    26995    +4841     
+ Misses      24738    24083     -655     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hansl
Copy link
Contributor Author

hansl commented Jun 9, 2025

@jedel1043

Can we add an #[export] attribute instead? IMO it should be a lot more readable and less surprising overall to be a bit more explicit in this case.

Could you give me an example of what that would look like? You can use the current example test module as template (export a const, function and class). Keep in mind the idea is to have a function that returns the module, so we would have to add that to the source as well.

I felt that having a mod was easy and explicit enough with the proc_macro above. The name of the module is irrelevant and it doesn't have to be public, so this cannot interfere with "valid" code.

@jedel1043
Copy link
Member

I stand corrected. I was thinking it would be a bit clunky to have something like a private const used throughout multiple public methods, but I see that the correct usage would be to have private functions, types and constants in the parent module, then the child module is the one with the boa_module attribute, which is nicer than having to add an #[export] tag to every single exported item.

@hansl hansl enabled auto-merge June 9, 2025 22:17
Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really impressive work! Couple of discussion points that I wanted to raise.

@jedel1043 jedel1043 added A-Enhancement New feature or request A-API Changes related to public APIs labels Jun 12, 2025
@jedel1043 jedel1043 added this to the next-release milestone Jun 12, 2025
@hansl hansl requested a review from jedel1043 June 13, 2025 03:46
@hansl
Copy link
Contributor Author

hansl commented Jun 13, 2025

@jedel1043 Done, changed the defaults to be more sensible.

Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!

@hansl hansl added this pull request to the merge queue Jun 13, 2025
Merged via the queue into boa-dev:main with commit f00677a Jun 13, 2025
15 checks passed
@hansl hansl deleted the module-proc-macro branch June 13, 2025 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-API Changes related to public APIs A-Enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants