-
Notifications
You must be signed in to change notification settings - Fork 55
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
JS Constructor Attr Support #754
JS Constructor Attr Support #754
Conversation
Slicing is not supported, so it's easier this way
This is to avoid calling `new` inside of a constructor method chain
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.
Overall this seems good but I really don't think we should ever be sharing codegen between constructors and regular JS methods: a codegenned method should be one or the other.
The reason is that constructor
has some subtle behavior: in a constructor
, you either mutate this
, or you return an object: If what you return is an Object (any object), that is the construction result.
We need to go through a constructor eventually since JS does not provide a good way to make objects with the right typeof
without using a constructor
.
What we should have is:
internalConstructor
: A non-static method that takesthis
and returns an object. This method should mutatethis
if necessary, and always returnthis
or another object of the right type:- For opaques: set up lifetimes, and set up
this.ptr
. Returnthis
- For structs: set subfields. Return
this
. - For enums: either return a cached object, the provided object, or (internal-only) set
this.value
and returnthis
- For opaques: set up lifetimes, and set up
constructor
: A thin wrapper that returnsthis.internalConstructor()
(when no default ctor), or something calls the default ctor / the internal ctor depending on the value of the first argument.fromFields
/fromValue
: Thin wrappers aroundnew Foo(exposeConstructor?, ...)
fromFfi
: We don't have this anymore, but this is justnew Foo(internalConstructor, ...)
and callsites already do that.
I don't think returning this
is strictly always necessary: for example the struct setup works fine without it, but it might be better from a hygeine point of view? Open to other ideas. The nice thing about this design is that the codegenned constructor can also be identical in that case.
Thoughts?
I think all of your suggestions sound good to avoid future headaches. I believe what you're describing for If you're curious as to what that looked like, the commit hash was When I have some time, I'll go about changing all |
On further reading though, I think I may be missing your point. My understanding now is that you'd like to completely remove any form of sharing generation logic for any method that is meant to be a default constructor. So we might move all that logic from |
No, that part is okay. What I don't want is for us to ever have the situation we have now where a piece of the codegen template generates either a regular function or a constructor, as it does now: we shouldn't have We should instead generate
They will still have to return an object at least for the enum case, because we cache enum objects. I don't believe They have to both mutate |
Ah, I believe I understand your point now. I'll start by moving the generation for |
@Manishearth I moved logic for generating Let me know if this matches what you had in mind! |
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.
praise: nice work!!
|
||
/// Used by `js_class.js.jinja`. If a constructor isn't overridden by #[diplomat::attr(auto, constructor)], this is the logic that `js_class.js.jinja` will use to determine whether or not to generate constructor code. | ||
/// Useful for hiding the fact that an out_struct has a constructor in typescript headers, for instance. | ||
show_default_ctor: bool, |
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.
thought (followup): we should probably move shared types into a shared ImplTemplate type, and have specific StructImplTemplate/etc
Fixes #718.
Current TODOs:
fromFields
,fromValue
, etc.) for when the default constructor is overridden.fromValue
)usage
is removable (I think this can be avoided by justreturn
ing a new constructed object)...args
) inconstructor
functions so those inspecting source can see what the default constructor takes for params