-
Notifications
You must be signed in to change notification settings - Fork 820
feat(compiler) variables as arguments for decorators #6451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ode called resolveVar
|
@johnjenkins It's more in step with utility type functions already added. |
johnjenkins
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely stuff!
I much prefer this approach (was a bit nervous regarding the potential cost in the last PR)
|
@tamb - before I release this, can you please write some docs for it 🙏 As this is a new feature it will be a minor release (so don't make changes in the v4.38 versioned doc, instead make changes here) |
Will this do @johnjenkins ? |
Add resolveVar function for compile-time variable resolution in @listen and @event decorators
What is the current behavior?
Currently, the
@Listenand@Eventdecorators only accept string literals as event names. This forces developers to hardcode event names as strings, which leads to:Example of current limitation:
GitHub Issue Number: N/A
What is the new behavior?
This PR introduces a new
resolveVar()function that allows developers to use const variables and object properties in@Listenand@Eventdecorators. The function resolves variable values at compile-time, providing:The
resolveVar()function is compile-time only and must be imported from@stencil/core:Features
constvariables with string literal valuesconstvariables withas constassertionsresolveVar()calls are replaced with resolved string valuesImplementation Details
resolveVar()function is detected during the decorator transformation phaseresolveVar()calls are replaced with their resolved string values at compile-timeDocumentation
Documentation updates should be added to:
resolveVarto the Events documentationstencil-public-runtime.tsDoes this introduce a breaking change?
This is a purely additive feature. Existing code using string literals in decorators continues to work exactly as before. The
resolveVar()function is optional and can be adopted incrementally.Testing
Unit Tests (Compiler Transformers)
src/compiler/transformers/test/decorator-utils.spec.tsas constassertionsIntegration Tests
✅
src/compiler/transformers/test/parse-listeners.spec.ts@Listen(resolveVar(MY_EVENT))with const variables@Listen(resolveVar(MY_EVENT))withas constassertions@Listen(resolveVar(EVENTS.MY_EVENT))with object properties✅
src/compiler/transformers/test/parse-events.spec.ts@Event({ eventName: resolveVar(MY_EVENT) })with const variables@Event({ eventName: resolveVar(EVENTS.MY_EVENT) })with object propertiesRuntime Unit Tests
✅
src/runtime/test/listen.spec.tsx@Listen(resolveVar(MY_EVENT))- verifies listener works correctly@Listen(resolveVar(EVENTS.MY_EVENT))- verifies listener works with object property✅
src/runtime/test/event.spec.tsx@Event({ eventName: resolveVar(MY_EVENT) })- verifies event emits correctly@Event({ eventName: resolveVar(EVENTS.MY_EVENT) })- verifies event emits with object propertyEnd-to-End Tests
test/end-to-end/src/resolve-var-events/resolve-var-events.e2e.ts@Event({ eventName: resolveVar(MY_EVENT) })- verifies event fires correctly@Listen(resolveVar(MY_EVENT))- verifies listener receives events@Event({ eventName: resolveVar(EVENTS.MY_EVENT) })with object property@Listen(resolveVar(EVENTS.MY_EVENT))with object propertyAll tests pass and follow existing testing patterns in the codebase.
Other information
Files Changed
Core Implementation:
src/declarations/stencil-public-runtime.ts- AddedresolveVarfunction declarationsrc/compiler/transformers/decorators-to-static/decorator-utils.ts- AddedresolveVardetection and resolution logicsrc/compiler/transformers/transform-utils.ts- EnhancedobjectLiteralToObjectMapto handleresolveVarin object literalssrc/compiler/transformers/decorators-to-static/listen-decorator.ts- Updated to pass diagnosticssrc/compiler/transformers/decorators-to-static/event-decorator.ts- Updated to pass diagnosticssrc/compiler/transformers/decorators-to-static/component-decorator.ts- Updated to pass diagnosticsTests:
src/compiler/transformers/test/decorator-utils.spec.ts- Unit tests forresolveVarresolutionsrc/compiler/transformers/test/parse-listeners.spec.ts- Integration tests for@ListenwithresolveVarsrc/compiler/transformers/test/parse-events.spec.ts- Integration tests for@EventwithresolveVarsrc/runtime/test/listen.spec.tsx- Runtime tests for@ListenwithresolveVarsrc/runtime/test/event.spec.tsx- Runtime tests for@EventwithresolveVartest/end-to-end/src/resolve-var-events/resolve-var-events.tsx- E2E test componenttest/end-to-end/src/resolve-var-events/resolve-var-events.e2e.ts- E2E testsError Handling
When
resolveVar()cannot resolve a value at compile-time, it provides helpful error messages:All errors are properly attached to the relevant AST nodes for better IDE integration.
Performance
No performance impact -
resolveVar()is resolved at compile-time and completely removed from the output. The resolved string values are identical to what developers would have written manually.Backward Compatibility
100% backward compatible. Existing code continues to work unchanged. The feature is opt-in and can be adopted incrementally.