Page MenuHomePhabricator

efl-mono: Remove initializer methods and add constructor parameters
Closed, ResolvedPublic

Description

As discussed in T7477, it turns out the initializer methods we have been using in C# (or the initializer lists used in C) are not meant as all-purpose configuration methods. Only a handful of properties can be reliably set in there, and those are the ones in the constructors section of the EO files.
This can be enforced at runtime by not allowing calls to forbidden method until the object has finalized construction, but, in C#, it is much simpler to just remove the initialization method completely, and turn the allowed properties into optional constructor parameters.

This means that all properties in the constructors section are turned into constructor parameters, so the @ctor_param tag from T7399 is not needed anymore and should be removed.

segfaultxavi triaged this task as High priority.Dec 5 2018, 10:19 AM
lauromoura lowered the priority of this task from High to TODO.
lauromoura raised the priority of this task from TODO to High.

I've just pushed a tentative patch to devs/lauromoura/constructor_params. It treats all constructor parameters as obligatory and removes the initialization callback.

Some comments regarding that branch:

  • Parameter names should be lower_case, otherwise it looks really weird :)
  • I thought we agreed constructor parameters should be optional, that is, they should have default values! (which default value? interesting question)
  • The new constructor parameters should have documentation (this is going to be interesting too)
  • There's still documentation generated for the init_cb parameter.

Some comments regarding that branch:

  • Parameter names should be lower_case, otherwise it looks really weird :)

Will do.

  • I thought we agreed constructor parameters should be optional, that is, they should have default values! (which default value? interesting question)

C constructors are easily made optional in practice by simply not calling them inside the efl_add call. But in C# you declare optional parameters with default values and you can't detect whether the received default value was explicitly passed by the caller or pulled from the default value. So, for C# with regular default parameters, we can assume optional constructors will always be called.

For the actual default values, Eolian has support for default value expressions in parameters/properties through the type(default_value) syntax. For parameters without explicit default values, what shall we assume? Zero/null/empty?

Also, parameters with default values will be bubbled down to be at the end of the parameter list, per C# rules.

If always calling all optional constructors is not an option, we could be wrapping the optional ones around something like an Optional<T> struct, so the constructor body could detect whether the given parameter was passed or not and decide to call the constructor function. This has the downside of making the constructor signature slightly more verbose with Optional<int>, Optional<string> parameters. But when invoking, implicit operators take care of converting T into the Optional<T>.

By the way, with this approach, what happens with optional constructors with multiple parameters and only some are given?

C# has a Nullable<T> type for nullable value types (int? is a shorthand for Nullable<int>) but this may cause confusion with reference types (classes) as null may be a valid parameter value in the latter case.

  • The new constructor parameters should have documentation (this is going to be interesting too)

I'll try to mimic the parameter expansion behavior into the documentation generator.

  • There's still documentation generated for the init_cb parameter.

Will do.

The only thing missing is the optional parameters.
I think we can use Nullable<T> for non-object types and for object types the only options are always going to be null for default values, or no default-value. So we can fix null as being a default and that's it. I don't think we need default-values.

@lauromoura is going to test this hypothesis in his branch

So, to summarize: all properties in the constructor section of EO files become parameters in the C# constructors. These parameters will be Nullable and have a default value of NULL (or the corresponding default value). Therefore, users can pass any non-default value they wish to these properties in the constructors, and address them by name if they want.
The constructor then will check all params and call the corresponding setters for those with non-default values.

Is that correct?

Looks pretty good to me. As @felipealmeida I don't think it is needed to allow users to pass default values for properties in the constructors. Because, to do that, just don't pass that property, duh!

lauromoura closed this task as Resolved.Feb 1 2019, 11:08 AM

Done with D7789