Paul Ishenin schrieb:

For some reason the visibility is completely ignored here. I can add a class helper to the strict private or even move it to another unit - it is always visible.

IMO class helper methods always should become visible as part of the class, regardless of where they are declared.

From the Delphi wiki:

"You can define and associate multiple helpers with a single type. However, only zero or one helper applies in any specific location in source code. The helper defined in the nearest scope will apply. Class or record helper scope is determined in the normal Delphi fashion (for example, right to left in the unit's uses clause)."

I.e. a single Helper reference (field) in the class definition is sufficient. This field cannot be persistent, instead it has to be initialized for every use case: whenever a helper is found in the compiled unit, or in one of its used units, it overwrites the Helper reference. Adding the helper elements to the class STB is not a valid solution, because another helper can become active at any time, during compilation.

The ancestors of the Helper class must be searched as well.


Also:

"Note that the class helper function MyFunc is called, because the class helper takes precedence over the actual class type."

That's bad, because this disallows to treat the helper like an ancestor, accessible in all derived classes :-(

Interesting questions:

1) Unit A defines an class helper for TFoo, then uses in the implementation section unit B, which also defines an helper for TFoo. According to the above rules the helper in A should become inaccessible and useless then.

2) Similarly multiple class helpers can be defined in the implementation section, which are used in the immediately following code, until the next helper declaration.

3) What about derived classes? Since derived classes are compiled independently, they never will use a reintroduced method in an class helper.

4) When class helpers are evaluated at compile time, according to the static object types (like properties are), then they could be handled just like the well known typecast hack:

type TMyFoo = class(TFoo)
  <helper methods>
  end;

with following casts of every TFoo reference into TMyFoo.
But TFoo derived types must be handled in the same way, so that I see no way around an extended search inside the TFoo STB.

5) What's the meaning of the "ancestor list"? IMO interfaces cannot be added by an class helper, and multiple inheritance is quite unlikely. Will the ancestor list allow to override interface *implementations*?

DoDi

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to