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<T> = 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<T> // [DCC Error] tclasshelper2.dpr(13):
E2003 Undeclared identifier: 'T'
//end;
//TFooHelper = class helper for TFoo<Integer> // [DCC Error]
tclasshelper2.dpr(17): E2086 Type 'TFoo<T>' is not yet completely defined
//end;
begin
end.
_______________________________________________
fpc-devel maillist - [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel