Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-30 Thread Sven Barth

On 30.12.2010 20:02, Dimitri Smits wrote:


- "Jonas Maebe"  schreef:
 >
 >
On 21 Dec 2010, at 00:16, Jonas Maebe wrote:

On 20 Dec 2010, at 21:37, Sven Barth wrote:
 >
 >

- should abstract methods be forbidden?


 > Yes, since
 > a) they are virtual
 > b) even if it were possible to have virtual methods, there would
be no way to override them with implementations that do something
(since you cannot inherit from a class helper)
 >


 >
Actually, it seems that inheritance is in fact allowed for Delphi-style
class helpers: http://qc.embarcadero.com/wc/qcmain.aspx?d=76577 (it's
not for Objective-C categories). But I'm still quite sure you cannot do
anything that requires changes to the VMT of the helped class.

 >
There are also at some extra checks that must be added for
constructors/destructors introduced via class helpers
(Objective-C/Pascal doesn't have constructors or destructors, so it
doesn't matter there):
*
http://docwiki.embarcadero.com/RADStudio/en/E2295_A_class_helper_cannot_introduce_a_destructor_(Delphi)

*
http://docwiki.embarcadero.com/RADStudio/en/E2296_A_constructor_introduced_in_a_class_helper_must_call_the_parameterless_constructor_of_the_helped_class_as_the_first_statement_(Delphi)

*
http://docwiki.embarcadero.com/RADStudio/en/E2358_Class_constructors_not_allowed_in_class_helpers_(Delphi)


 >

hi,

it seems that the virtual methods can be overridden (AOP style) using
the TVirtualMethodInterceptor that comes with Delphi XE. It can also be
on a per instance base (as opposed to on a per type) if I've read up on
it correctly.

I'd say that would be a better candidate for that purpose/intent/use case.


I don't know whether I understand you right, but we aren't talking about 
how we should allow the override of virtual methods, but about what 
Delphi allows regarding class helpers and what not, so we can have a as 
compatible as possible implementation in FPC.


Regards,
Sven
___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-30 Thread Dimitri Smits

- "Jonas Maebe"  schreef: 
> 
> 

On 21 Dec 2010, at 00:16, Jonas Maebe wrote: 



On 20 Dec 2010, at 21:37, Sven Barth wrote: 
> 
> 

- should abstract methods be forbidden? 
> Yes, since 
> a) they are virtual 
> b) even if it were possible to have virtual methods, there would be no way to 
> override them with implementations that do something (since you cannot 
> inherit from a class helper) 
> 
> 
Actually, it seems that inheritance is in fact allowed for Delphi-style class 
helpers: http://qc.embarcadero.com/wc/qcmain.aspx?d=76577 (it's not for 
Objective-C categories). But I'm still quite sure you cannot do anything that 
requires changes to the VMT of the helped class. 

> 
There are also at some extra checks that must be added for 
constructors/destructors introduced via class helpers (Objective-C/Pascal 
doesn't have constructors or destructors, so it doesn't matter there): 
* 
http://docwiki.embarcadero.com/RADStudio/en/E2295_A_class_helper_cannot_introduce_a_destructor_(Delphi)
 
* 
http://docwiki.embarcadero.com/RADStudio/en/E2296_A_constructor_introduced_in_a_class_helper_must_call_the_parameterless_constructor_of_the_helped_class_as_the_first_statement_(Delphi)
 
* 
http://docwiki.embarcadero.com/RADStudio/en/E2358_Class_constructors_not_allowed_in_class_helpers_(Delphi)
 

> 

hi, 

it seems that the virtual methods can be overridden (AOP style) using the 
TVirtualMethodInterceptor that comes with Delphi XE. It can also be on a per 
instance base (as opposed to on a per type) if I've read up on it correctly. 

I'd say that would be a better candidate for that purpose/intent/use case. 

kind regards, 
Dimitri Smits 


___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-21 Thread Jonas Maebe


On 21 Dec 2010, at 10:13, Sven Barth wrote:


Am 21.12.2010 00:16, schrieb Jonas Maebe:


Note that Delphi-style class helpers have several limitations that  
still have to be added to your patch:
a) from http://docwiki.embarcadero.com/RADStudio/2010/en/Class_and_Record_Helpers 
 : "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)." -- In Objective-C, there is no limit on the number  
of categories for a class that applies at the same time.


I don't know whether we should really follow this limitation (and  
when, then only in mode Delphi)


I would suggest asking on the Embarcadero forums what the reason is  
for this limitation. It would be annoying to have to add to wiki/ 
User_Changes_2.6.2 "Disabled multiple class helpers for a single class  
because it breaks/conflicts with/... X", like we have had to do  
already with several other cases where we removed what we considered  
to be useless limitations of Delphi features. The fact that it works  
in Objective-C/Pascal does not mean that it also fits to Object  
Pascal, because both languages are quite different (and because  
Objective-C/Pascal has a complex runtime system that does a lot of  
things behind your back).


Regarding some of the other limitations mentioned earlier: it seems  
that in Delphi 2010, you can add virtual methods to a class helper: http://windwings.wordpress.com/2009/10/07/turbocharging-delphi-2010-adding-dynamic-functionality-to-3rd-party-frameworks-read-vcl/ 
. You cannot override any methods of a helped class, but you can  
override virtual methods defined in one class helper in a class helper  
that inherits from it. Apparently support for class constructors/ 
destructors has also been added to class helpers.


This feature (virtual class helper methods) might be part of the  
reason why only one class helper can be used, depending on how they  
handle the class helper VMTs. You start getting some kind of multiple  
inheritance with multiple VMTs in terms of figuring out which class  
helper VMT to pass when calling one class helper method from another  
class helper.


Take this example:

*** unit1:

type
  tclasshelperbase = class helper for tobject
procedure test; virtual;
  end;

  ttestcaller = class helper for tobject
procedure calltest;
  end;


procedure tclasshelperbase.test;
  begin
writeln('in base');
  end;

procedure ttestcaller.calltest;
  begin
test;
  end;

*** unit 2:

type
  tclasshelperderived = class helper(tclasshelperbase) for tobject
procedure test; override;
  end;

procedure tclasshelperderived.test;
  begin
writeln('in derived');
  end;

*** main program:
uses
  unit1, unit2;
var
  o: tobject;
begin
  o:=tobject.create;
  o.calltest;
end.

Now which "test" should be called from ttestcaller.calltest? Since  
both unit1 and unit2 are in scope, I'd assume  
tclasshelperderived.test. But how does ttestcaller.calltest get the  
VMT of tclasshelperderived? Do you pass a linked list or array of VMTs  
of all class helper hierarchies currently in scope to all class helper  
routines, which then walk this list/array every time in search for the  
appropriate VMT to use?



Jonas
___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-21 Thread Paul Ishenin

21.12.2010 16:20, Sven Barth wrote:

http://docwiki.embarcadero.com/RADStudio/en/E2358_Class_constructors_not_allowed_in_class_helpers_(Delphi)



As we don't have them yet...


we have.

Best regards,
Paul Ishenin

___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-21 Thread Sven Barth

Am 21.12.2010 00:23, schrieb Jonas Maebe:


On 21 Dec 2010, at 00:16, Jonas Maebe wrote:


On 20 Dec 2010, at 21:37, Sven Barth wrote:


- should abstract methods be forbidden?


Yes, since
a) they are virtual
b) even if it were possible to have virtual methods, there would be no
way to override them with implementations that do something (since you
cannot inherit from a class helper)


Actually, it seems that inheritance is in fact allowed for Delphi-style
class helpers: http://qc.embarcadero.com/wc/qcmain.aspx?d=76577 (it's
not for Objective-C categories). But I'm still quite sure you cannot do
anything that requires changes to the VMT of the helped class.



Ok... I should be able to implement that rather easy.


There are also at some extra checks that must be added for
constructors/destructors introduced via class helpers
(Objective-C/Pascal doesn't have constructors or destructors, so it
doesn't matter there):
*
http://docwiki.embarcadero.com/RADStudio/en/E2295_A_class_helper_cannot_introduce_a_destructor_(Delphi)


Should be easy to check.


*
http://docwiki.embarcadero.com/RADStudio/en/E2296_A_constructor_introduced_in_a_class_helper_must_call_the_parameterless_constructor_of_the_helped_class_as_the_first_statement_(Delphi)


Ok... O.o that will be an interesting one.


*
http://docwiki.embarcadero.com/RADStudio/en/E2358_Class_constructors_not_allowed_in_class_helpers_(Delphi)


As we don't have them yet...

Regards,
Sven
___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-21 Thread Sven Barth

Am 21.12.2010 00:16, schrieb Jonas Maebe:


On 20 Dec 2010, at 21:37, Sven Barth wrote:


I have taken the time to implement a first version of Delphi's class helpers. 
Thanks to Jonas' code for Objective C categories it was a rather easy to get 
that working.


Note that Delphi-style class helpers have several limitations that still have 
to be added to your patch:
a) from http://docwiki.embarcadero.com/RADStudio/2010/en/Class_and_Record_Helpers : 
"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)." -- In 
Objective-C, there is no limit on the number of categories for a class that applies at 
the same time.


I don't know whether we should really follow this limitation (and when, 
then only in mode Delphi)



b) afaik, Delphi class helpers cannot contain virtual methods, and definitely 
cannot override methods defined in a parent class (the used VMT is that of the 
helped class, so no additions/changes to the class that require VMT changes are 
allowed or even possible)


- should class helpers be able to be instantiated or even referenced in any 
way? (including forward declarations)


No. They are not first class entities, they just add a bunch of method 
declarations to the scope of the extended class.


- should class helpers be allowed to override/reintroduce methods?


Definitely no override. I don't know about reintroduce.


- should class helpers be able to extend other class helpers (as class helpers 
are implemented as child classes of the extended class this might currently be 
possible)?


No, that does not make any semantic sense. How they are implemented in the 
compiler is irrelevant.


- should abstract methods be forbidden?


Yes, since
a) they are virtual
b) even if it were possible to have virtual methods, there would be no way to 
override them with implementations that do something (since you cannot inherit 
from a class helper)



I'll take your answers into account.

Regards,
Sven
___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-20 Thread Jonas Maebe

On 21 Dec 2010, at 03:01, Paul Ishenin wrote:

> After reading of Jonas mail and following to QC I found that next example 
> indeed works:
> 
>  TFooHelper1 = class helper(TFooHelper) for TFoo
>  end;

I think it's probably related to the fact that at most one class helper can be 
used at a time. If you could not inherit from other class helpers, you would to 
completely reimplement them if you wanted to add one extra method later in 
another unit.


Jonas___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-20 Thread Paul Ishenin

21.12.2010 8:48, Paul Ishenin wrote:

- should class helpers be able to extend other class helpers (as class
helpers are implemented as child classes of the extended class this
might currently be possible)?


no


After reading of Jonas mail and following to QC I found that next 
example indeed works:


  TFooHelper1 = class helper(TFooHelper) for TFoo
  end;

Best regards,
Paul Ishenin

___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-20 Thread Paul Ishenin

21.12.2010 3:37, Sven Barth wrote:


Especially at the core devs, but maybe also for other interested persons
I have the following questions regarding the implementation of this
feature:
- should class helpers have access to protected fields of the extended
class? I propose not or this would beat the complete idea of "sealed" (I
also believe that Delphi doesn't allow it as well)


Protected, strict protected and private but not strict private.


- should class helpers be able to be instantiated or even referenced in
any way? (including forward declarations)


no


- should class helpers be allowed to override/reintroduce methods?


reintroduce - yes, but since class helper is not a child class using 
reitroduce does not do anything.



- should class helpers be able to extend other class helpers (as class
helpers are implemented as child classes of the extended class this
might currently be possible)?


no


- should class helpers be able to implement interfaces?


This needs to be tested but I don't think they can. You can't define a 
helper that implements interface - so all interfaces should be listed in 
class. Another thing that you can reintroduce QueryInterface, 
GetInterface in the helper but I don't think they will be used by 'is' 
and 'as' operators.



- can/should "message" methods be forbidden?


In delphi they are not forbidden but also they can't be reached by 
Dispatch call.



- should abstract methods be forbidden?


In delphi they are not forbidden and require an implementation. It looks 
tht delphi skips 'abstract'. Also delphi skips 'virtual' and 'dynamic'. 
I think in FPC this should be forbidden.



- should a class helper for class X hide a method which was introduced
in a subclass of X?


no


- can class helpers extend generic classes?


no one example I tried was able to compile

I have attached few tests which answers to most of your questions.

Best regards,
Paul Ishenin
program tclasshelper1;

{$APPTYPE CONSOLE}

uses
  Messages;

type
  TFoo = class(TObject)
  strict private
SP1: Integer;
  strict protected
SP2: Integer;
  private
P1: Integer;
  protected
P2: Integer;
  public
function Test: Integer;
procedure VirtualMethod; virtual;
  end;

  TFoo1 = class(TFoo)
  public
function Test: Integer;
  end;

  // test forward declaration
  // TFooHelper = class helper for TFoo; [DCC Error] tclasshelper1.dpr(17): 
E2029 'END' expected but ';' found

  TFooHelper = class helper for TFoo
  public
function Test: Integer;
procedure TestFieldsAccess;
// procedure VirtualMethod; override; // [DCC Error] tclasshelper1.dpr(25): 
E2137 Method 'VirtualMethod' not found in base class
procedure TestVirtual; virtual;
procedure TestDynamic; dynamic;
//procedure TestAbstract; virtual; abstract; // [DCC Error] 
tclasshelper1.dpr(28): E2065 Unsatisfied forward or external declaration: 
'TFooHelper.TestAbstract'
procedure TestWM(var Message: TMessage); message WM_APP + 1;
property PTest: Integer read Test;
  end;

  //TooHelper1 = class(TFooHelper) // [DCC Error] tclasshelper1.dpr(28): E2021 
Class type required
  //end;

  //TFooHelper1 = class helper for TFooHelper // [DCC Error] 
tclasshelper1.dpr(32): E2021 Class type required
  //end;

{ TFooHelper }

function TFooHelper.Test: Integer;
begin
  Result := 3;
end;

procedure TFooHelper.TestDynamic;
begin
  //
end;

procedure TFooHelper.TestFieldsAccess;
begin
  //SP1 := 1; // [DCC Error] tclasshelper1.dpr(26): E2003 Undeclared 
identifier: 'SP1'
  SP2 := 1;
  P1 := 1;
  P2 := 1;
end;

procedure TFooHelper.TestVirtual;
begin
  //
end;

procedure TFooHelper.TestWM(var Message: TMessage);
begin
  Message.Result := 1;
end;

{ TFoo }

function TFoo.Test: Integer;
begin
  Result := 1;
end;

procedure TFoo.VirtualMethod;
begin
  SP1 := 1;
end;

{ TFoo1 }

function TFoo1.Test: Integer;
begin
  Result := 2;
end;

var
  Foo: TFoo;
  Foo1: TFoo1;
  Message: TMessage;
begin
  Foo := TFoo.Create;
  Foo.TestFieldsAccess;
  if Foo.Test <> 3 then
halt(1);

  Message.Msg := WM_APP + 1;
  Message.Result := 0;

  { message members can't be reached in class helpers }
  Foo.Dispatch(Message);
  if Message.Result <> 0 then
halt(2);

  Foo.Free;
  Foo1 := TFoo1.Create;
  if Foo1.Test <> 2 then
halt(3);
  Foo1.Free;
  WriteLn('ok');
end.
program tclasshelper2;

{$APPTYPE CONSOLE}
type
  TFoo = class
  protected
F: T;
  end;

  //TFooHelper = class helper for TFoo //[DCC Error] tclasshelper2.dpr(10): 
E2003 Undeclared identifier: 'TFoo'
  //end;

  //TFooHelper = class helper for TFoo // [DCC Error] tclasshelper2.dpr(13): 
E2003 Undeclared identifier: 'T'
  //end;

  //TFooHelper = class helper for TFoo // [DCC Error] 
tclasshelper2.dpr(17): E2086 Type 'TFoo' is not yet completely defined
  //end;

begin
end.
___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-20 Thread Paul Ishenin

21.12.2010 3:37, Sven Barth wrote:

Hello together!

I have taken the time to implement a first version of Delphi's class 
helpers. Thanks to Jonas' code for Objective C categories it was a 
rather easy to get that working.


I have yet to test the compatibility of this implementation with 
Delphi and this is where the FPC community comes in. I'd like you 
(@all list readers) - if possible - to test this extension with tasks 
you'd use them in and also to test what behaves differently from 
Delphi if you have a current Delphi version available (I believe you 
need Delphi 2007 or newer for this).

I will do some tests.

I have attached the patch which implements the class helper syntax in 
the trunk compiler. Please note that this might not be the final 
version, so please do not rely on the syntax and especially the behavior.


Maybe you should create a branch so testing will go easily? I can't give 
you a branch myself but Florian usually do this is there is a need.


Best regards,
Paul Ishenin
___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-20 Thread Jonas Maebe

On 21 Dec 2010, at 00:16, Jonas Maebe wrote:

> On 20 Dec 2010, at 21:37, Sven Barth wrote:
> 
>> - should abstract methods be forbidden?
> 
> Yes, since
> a) they are virtual
> b) even if it were possible to have virtual methods, there would be no way to 
> override them with implementations that do something (since you cannot 
> inherit from a class helper)

Actually, it seems that inheritance is in fact allowed for Delphi-style class 
helpers: http://qc.embarcadero.com/wc/qcmain.aspx?d=76577 (it's not for 
Objective-C categories). But I'm still quite sure you cannot do anything that 
requires changes to the VMT of the helped class.

There are also at some extra checks that must be added for 
constructors/destructors introduced via class helpers (Objective-C/Pascal 
doesn't have constructors or destructors, so it doesn't matter there):
* 
http://docwiki.embarcadero.com/RADStudio/en/E2295_A_class_helper_cannot_introduce_a_destructor_(Delphi)
* 
http://docwiki.embarcadero.com/RADStudio/en/E2296_A_constructor_introduced_in_a_class_helper_must_call_the_parameterless_constructor_of_the_helped_class_as_the_first_statement_(Delphi)
* 
http://docwiki.embarcadero.com/RADStudio/en/E2358_Class_constructors_not_allowed_in_class_helpers_(Delphi)


Jonas___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RFC: Delphi style class helpers

2010-12-20 Thread Jonas Maebe

On 20 Dec 2010, at 21:37, Sven Barth wrote:

> I have taken the time to implement a first version of Delphi's class helpers. 
> Thanks to Jonas' code for Objective C categories it was a rather easy to get 
> that working.

Note that Delphi-style class helpers have several limitations that still have 
to be added to your patch:
a) from 
http://docwiki.embarcadero.com/RADStudio/2010/en/Class_and_Record_Helpers : 
"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)." -- In Objective-C, there is no limit on the number of 
categories for a class that applies at the same time.
b) afaik, Delphi class helpers cannot contain virtual methods, and definitely 
cannot override methods defined in a parent class (the used VMT is that of the 
helped class, so no additions/changes to the class that require VMT changes are 
allowed or even possible)

> - should class helpers be able to be instantiated or even referenced in any 
> way? (including forward declarations)

No. They are not first class entities, they just add a bunch of method 
declarations to the scope of the extended class.

> - should class helpers be allowed to override/reintroduce methods?

Definitely no override. I don't know about reintroduce.

> - should class helpers be able to extend other class helpers (as class 
> helpers are implemented as child classes of the extended class this might 
> currently be possible)?

No, that does not make any semantic sense. How they are implemented in the 
compiler is irrelevant.

> - should abstract methods be forbidden?

Yes, since
a) they are virtual
b) even if it were possible to have virtual methods, there would be no way to 
override them with implementations that do something (since you cannot inherit 
from a class helper)


Jonas

___
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel