Re: [fpc-devel] Re: RFC: Delphi style class helpers
In our previous episode, Paul Ishenin said: > > 07.01.2011 17:56, Sven Barth wrote: > >> > >> Oops. I forgot to add a "uses uchlp35" to tchlp35. Can you retest > >> with that change, please? > > It compiles fine. > Ah.. and res = 1. So the test fails. Same with XE. ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
Am 07.01.2011 12:02, schrieb Paul Ishenin: 07.01.2011 18:00, Paul Ishenin wrote: 07.01.2011 17:56, Sven Barth wrote: Oops. I forgot to add a "uses uchlp35" to tchlp35. Can you retest with that change, please? It compiles fine. Ah.. and res = 1. So the test fails. Ok, thanks (no need to send the binary then ^^) Regards, Sven ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
Am 07.01.2011 12:00, schrieb Paul Ishenin: 07.01.2011 17:56, Sven Barth wrote: Oops. I forgot to add a "uses uchlp35" to tchlp35. Can you retest with that change, please? It compiles fine. Can you send me the binary, please, cause I'm interested in the runtime behavior of that test. Regards, Sven ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
07.01.2011 18:00, Paul Ishenin wrote: 07.01.2011 17:56, Sven Barth wrote: Oops. I forgot to add a "uses uchlp35" to tchlp35. Can you retest with that change, please? It compiles fine. Ah.. and res = 1. So the test fails. Best regards, Paul Ishenin ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
Am 07.01.2011 11:43, schrieb Jonas Maebe: On 07 Jan 2011, at 10:30, Sven Barth wrote: Should I use new error messages like "reference to class helper not allowed here" and so on or should I rely on the messages that are already there? If the first: what needs to be changed to add a new message? When you can reuse (or *slightly* modify/generalise) an existing message, do so. Otherwise add a new one. To do so, edit compiler/msg/errore.msg and add a new entry at the end of the appropriate category, along with a description. If you're not sure, search for a related message and add it to the end of its category. See the text at the top for an explanation of the format of the messages. When you "make" the compiler, the message files will automatically be regenerated from errore.msg Ok, thanks. Regards, Sven ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
Am 07.01.2011 11:20, schrieb Paul Ishenin: 07.01.2011 16:40, Marco van de Voort wrote: Embarcadero Delphi for Win32 compiler version 22.0 Copyright (c) 1983,2010 Embarcadero Technologies, Inc. tchlp36.dpr(23) Warning: W1036 Variable 'f' might not have been initialized tchlp36.dpr(25) 26 lines, 0.03 seconds, 13512 bytes code, 13104 bytes data. While it compiles I think it is bug I believe. This should not be implemented so in FPC. Anyway, this better to report to Embarcadero forum and/or QC. It seems to be intentional. If I change the code to the following: === source begin === program tchlp36; type TBar = class end; TObjectHelper = class helper for TBar procedure Test; end; TFoo = class end; TFooHelper = class helper(TObjectHelper) for TFoo end; procedure TObjectHelper.Test; begin end; var f: TFoo; begin f.Test; end. === source end === I get the following output now: === output begin === P:\test>"c:\Programme\CodeGear\RAD Studio\5.0\bin\DCC32.EXE" tchlp36.pp CodeGear Delphi für Win32 Compiler-Version 18.5 Copyright (c) 1983,2007 CodeGear tchlp36.pp(19) Fehler: E2294 Eine von 'TObjectHelper' abgeleitete unterstützende Klasse steht nur für von 'TBar' abgeleitete Klassen zur Verfügung tchlp36.pp(30) === output end === Rough translation of the error: A class helper that inherits from 'TObjectHelper' is only available for classes that inherit from 'TBar'. Regards, Sven ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
07.01.2011 17:56, Sven Barth wrote: Oops. I forgot to add a "uses uchlp35" to tchlp35. Can you retest with that change, please? It compiles fine. Best regards, Paul Ishenin ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
Am 07.01.2011 10:40, schrieb Marco van de Voort: In our previous episode, Sven Barth said: In the last few days I've written quite a few tests regarding class helpers and have come across some interesting cases. I've used Delphi 2007 to compile these tests. C:\testing>dcc32 tchlp20.dpr Embarcadero Delphi for Win32 compiler version 22.0 Copyright (c) 1983,2010 Embarcadero Technologies, Inc. tchlp20.dpr(14) Error: E2527 Helper type 'TObjectHelper' cannot be used in declarations tchlp20.dpr(19) Ok, then it's a bug indeed. Thanks. Embarcadero Delphi for Win32 compiler version 22.0 Copyright (c) 1983,2010 Embarcadero Technologies, Inc. tchlp36.dpr(23) Warning: W1036 Variable 'f' might not have been initialized tchlp36.dpr(25) 26 lines, 0.03 seconds, 13512 bytes code, 13104 bytes data. Embarcadero Delphi for Win32 compiler version 22.0 Copyright (c) 1983,2010 Embarcadero Technologies, Inc. tchlp35.dpr(6) Error: E2003 Undeclared identifier: 'TObjectHelperA' tchlp35.dpr(6) Error: E2022 Class helper type required tchlp35.dpr(7) Error: E2137 Method 'VirtualTest' not found in base class tchlp35.dpr(20) Error: E2003 Undeclared identifier: 'Test' tchlp35.dpr(25) uchlp36 compiles without warnings Oops. I forgot to add a "uses uchlp35" to tchlp35. Can you retest with that change, please? Regards, Sven ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
On 07 Jan 2011, at 11:50, Paul Ishenin wrote: 07.01.2011 17:43, Jonas Maebe wrote: When you can reuse (or *slightly* modify/generalise) an existing message, do so. Otherwise add a new one. To do so, edit compiler/ msg/errore.msg and add a new entry at the end of the appropriate category, along with a description. If you're not sure, search for a related message and add it to the end of its category. See the text at the top for an explanation of the format of the messages. When you "make" the compiler, the message files will automatically be regenerated from errore.msg Sometimes I need to edit the message. In this case I also modify other error[lang].msg files. Is this correct or I should use some automated process? There's a helper utility (utils/msgdif.pp), but I don't think it handles changed messages (except for a change in severity). So it's ok to manually modify the other language msg files. Jonas ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
07.01.2011 17:43, Jonas Maebe wrote: When you can reuse (or *slightly* modify/generalise) an existing message, do so. Otherwise add a new one. To do so, edit compiler/msg/errore.msg and add a new entry at the end of the appropriate category, along with a description. If you're not sure, search for a related message and add it to the end of its category. See the text at the top for an explanation of the format of the messages. When you "make" the compiler, the message files will automatically be regenerated from errore.msg Sometimes I need to edit the message. In this case I also modify other error[lang].msg files. Is this correct or I should use some automated process? Best regards, Paul Ishenin ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
On 07 Jan 2011, at 10:30, Sven Barth wrote: Should I use new error messages like "reference to class helper not allowed here" and so on or should I rely on the messages that are already there? If the first: what needs to be changed to add a new message? When you can reuse (or *slightly* modify/generalise) an existing message, do so. Otherwise add a new one. To do so, edit compiler/msg/ errore.msg and add a new entry at the end of the appropriate category, along with a description. If you're not sure, search for a related message and add it to the end of its category. See the text at the top for an explanation of the format of the messages. When you "make" the compiler, the message files will automatically be regenerated from errore.msg Jonas ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
07.01.2011 16:40, Marco van de Voort wrote: Embarcadero Delphi for Win32 compiler version 22.0 Copyright (c) 1983,2010 Embarcadero Technologies, Inc. tchlp36.dpr(23) Warning: W1036 Variable 'f' might not have been initialized tchlp36.dpr(25) 26 lines, 0.03 seconds, 13512 bytes code, 13104 bytes data. While it compiles I think it is bug I believe. This should not be implemented so in FPC. Anyway, this better to report to Embarcadero forum and/or QC. Best regards, Paul Ishenin ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
In our previous episode, Sven Barth said: > > In the last few days I've written quite a few tests regarding class > helpers and have come across some interesting cases. I've used Delphi > 2007 to compile these tests. C:\testing>dcc32 tchlp20.dpr Embarcadero Delphi for Win32 compiler version 22.0 Copyright (c) 1983,2010 Embarcadero Technologies, Inc. tchlp20.dpr(14) Error: E2527 Helper type 'TObjectHelper' cannot be used in declarations tchlp20.dpr(19) Embarcadero Delphi for Win32 compiler version 22.0 Copyright (c) 1983,2010 Embarcadero Technologies, Inc. tchlp36.dpr(23) Warning: W1036 Variable 'f' might not have been initialized tchlp36.dpr(25) 26 lines, 0.03 seconds, 13512 bytes code, 13104 bytes data. Embarcadero Delphi for Win32 compiler version 22.0 Copyright (c) 1983,2010 Embarcadero Technologies, Inc. tchlp35.dpr(6) Error: E2003 Undeclared identifier: 'TObjectHelperA' tchlp35.dpr(6) Error: E2022 Class helper type required tchlp35.dpr(7) Error: E2137 Method 'VirtualTest' not found in base class tchlp35.dpr(20) Error: E2003 Undeclared identifier: 'Test' tchlp35.dpr(25) uchlp36 compiles without warnings ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] Re: RFC: Delphi style class helpers
Hello again!
In the last few days I've written quite a few tests regarding class
helpers and have come across some interesting cases. I've used Delphi
2007 to compile these tests.
Case 1:
The following code compiles in Delphi
=== source begin ===
program tchlp20;
{$ifdef fpc}
{$mode objfpc}
{$endif}
type
TObjectHelper = class helper for TObject
end;
TSomeRec = record
helper: TObjectHelper;
end;
begin
end.
=== source end ===
This is strange, because every other reference to a class helper (
variable declaration, parameter, parent class) results either in a error
or even in an internal error (haha ^^). Can someone test with a newer
version of Delphi (e.g. XE)?
If a newer Delphi also successfully generates a binary for this, should
I consider this a bug or does someone knew more about this?
Case 2:
The following code compiles as well, which scares me a bit, cause I have
to implement that as well :P
=== source begin ===
program tchlp36;
type
TObjectHelper = class helper for TObject
procedure Test;
end;
TFoo = class
end;
TFooHelper = class helper(TObjectHelper) for TFoo
end;
procedure TObjectHelper.Test;
begin
end;
var
f: TFoo;
begin
f.Test;
end.
=== source end ===
I yet need to test what happens if the extended classes don't inherit
from eachother...
Case 3:
I have attached two sources (tchlp35.pp and uchlp35.pp) for a test
regarding virtual methods in class helpers. This code does not compile
in Delphi 2007, but it might in Delphi XE. So could someone who has
access to a Delphi XE compile those tests and send me the binary, please
(you need to compile the unit first, cause Delphi does not find *.pp
sources)?
At last I have a question regarding compiler development:
Should I use new error messages like "reference to class helper not
allowed here" and so on or should I rely on the messages that are
already there? If the first: what needs to be changed to add a new message?
Regards,
Sven
{ tests virtual methods inside class helpers }
program tchlp35;
type
TObjectHelperB = class helper(TObjectHelperA) for TObject
function VirtualTest: Integer; override;
end;
function TObjectHelperB.VirtualTest: Integer;
begin
Result := 2;
end;
var
o: TObject;
res: Integer;
begin
o := TObject.Create;
res := o.Test;
if res <> 2 then
Halt(1);
end.
unit uchlp35;
{$ifdef fpc}
{$mode objfpc}{$H+}
{$endif}
interface
type
TObjectHelperA = class helper for TObject
function Test: Integer;
function VirtualTest: Integer; virtual;
end;
implementation
function TObjectHelperA.Test: Integer;
begin
Result := VirtualTest;
end;
function TObjectHelperA.VirtualTest: Integer;
begin
Result := 1;
end;
end.
___
fpc-devel maillist - [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
22.12.2010 15:00, Sven Barth wrote:
Would you please test the following:
- identifier visibility if class helper and extended class reside in
different units (because I can't believe that a helper can access
private members while a derived class can't)
Class helper can access the same as derived class
- can overloaded methods be defined? (e.g. class contains "Test(a:
String);" and helper contains "Test(a: Integer);")
If overload is used then yes, if not then no. Look at test for more info.
- what happens if you define a method in the helper that has the same
name as a virtual method in the extended class (without "override" of
course ^^)
Look at test.
- is a class helper method used in a derived class if the derived class
does not contain a method with the same name?
Look at test.
- class helper and class in two different units, both containing a
method with the same name. which method get's called if the unit with
the class is used before the unit with the class helper in the main
program?
Will test later.
- can class helpers have fields and if so is their value saved somehow?
They can't.
- can class helpers extend interfaces?
How you see this?
- can a class helper reintroduce a virtual method from the extended class?
Yes.
Best regards,
Paul Ishenin
program tclasshelper2;
{$APPTYPE CONSOLE}
uses
tuclasshelper1 in 'tuclasshelper1.pas';
type
TFooHelper1 = class helper for TFoo
public
//F4: Integer; // [DCC Error] tclasshelper2.dpr(11): E2169 Field definition
not allowed after methods or properties
//var F4: Integer; // [DCC Error] tclasshelper2.dpr(12): E2029 'END'
expected but 'VAR' found
procedure TestAccess;
procedure TestOverload(I: Integer);
procedure TestOverload1(I: Integer); overload;
function TestVirtual: Integer;
end;
TFoo2 = class(TFoo)
//function TestVirtual: Integer; override; // [DCC Error]
tclasshelper2.dpr(18): E2170 Cannot override a non-virtual method
function TestVirtual1: Integer;
end;
{ TFooHelper1 }
procedure TFooHelper1.TestAccess;
begin
// F1 := 1; [DCC Error] tclasshelper2.dpr(18): E2003 Undeclared identifier:
'F1'
F2 := 1;
F3 := 1;
end;
procedure TFooHelper1.TestOverload(I: Integer);
begin
//
end;
procedure TFooHelper1.TestOverload1(I: Integer);
begin
//
end;
function TFooHelper1.TestVirtual: Integer;
begin
Result := 2;
end;
{ TFoo2 }
function TFoo2.TestVirtual1: Integer;
begin
Result := TestVirtual;
end;
var
F: TFoo;
F1: TFoo1;
F2: TFoo2;
begin
F := TFoo.Create;
//F.TestOverload('String'); // [DCC Error] tclasshelper2.dpr(33): E2010
Incompatible types: 'Integer' and 'string'
F.TestOverload1('String');
F.TestOverload1(10);
F.Free;
// Test virtual reintroduced in helper
F := TFoo1.Create;
if F.TestVirtual <> 2 then
halt(1);
F.Free;
F := TFoo2.Create;
if F.TestVirtual <> 2 then
halt(2);
if TFoo2(F).TestVirtual1 <> 2 then
halt(3);
F.Free;
F1 := TFoo1.Create;
if F1.TestVirtual <> 3 then
halt(4);
F1.Free;
F2 := TFoo2.Create;
if F2.TestVirtual <> 2 then
halt(5);
if F2.TestVirtual1 <> 2 then
halt(6);
F2.Free;
WriteLn('ok');
end.
unit tuclasshelper1;
interface
type
TFoo = class
private
F1: Integer;
strict protected
F2: Integer;
public
F3: Integer;
procedure TestOverload(S: String);
procedure TestOverload1(S: String); overload;
function TestVirtual: Integer; virtual;
end;
TFoo1 = class(TFoo)
function TestVirtual: Integer; override;
end;
implementation
{ TFoo }
procedure TFoo.TestOverload(S: String);
begin
//
end;
procedure TFoo.TestOverload1(S: String);
begin
//
end;
function TFoo.TestVirtual: Integer;
begin
Result := 1;
end;
{ TFoo1 }
function TFoo1.TestVirtual: Integer;
begin
Result := 3;
end;
end.
___
fpc-devel maillist - [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Re: RFC: Delphi style class helpers
22.12.2010 15:00, Sven Barth wrote: we have. And here I thought that I'm closely following FPC development... that must have slipt my attention. How embarrassing. -.- They still don't work the same way as in delphi. They are initialization sections but not "clever" :( I was not able to find a solution how to tell linker not to reference that sections by init/final tables. Maybe I should write a wiki page to have the "specification" saved somewhere :) This is a good idea. I will try to answer to your other questions with a new test. Best regards, Paul Ishenin ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] Re: RFC: Delphi style class helpers
Paul Ishenin wrote: 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. And here I thought that I'm closely following FPC development... that must have slipt my attention. How embarrassing. -.- Paul Ishenin wrote: I have attached few tests which answers to most of your questions. Thank you for the tests. They indeed solved some questions, but some are still left. Would you please test the following: - identifier visibility if class helper and extended class reside in different units (because I can't believe that a helper can access private members while a derived class can't) - can overloaded methods be defined? (e.g. class contains "Test(a: String);" and helper contains "Test(a: Integer);") - what happens if you define a method in the helper that has the same name as a virtual method in the extended class (without "override" of course ^^) - is a class helper method used in a derived class if the derived class does not contain a method with the same name? - class helper and class in two different units, both containing a method with the same name. which method get's called if the unit with the class is used before the unit with the class helper in the main program? - can class helpers have fields and if so is their value saved somehow? - can class helpers extend interfaces? - can a class helper reintroduce a virtual method from the extended class? Jonas Maebe wrote: 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: [illustrative example] This could indeed be the reason why only one class helper is used. So either we follow Delphi compatibility and allow virtual methods in class helpers and forbidding the use of multiple class helpers or forbidding virtual methods and allowing the use of multiple class helpers (although I must admit that I don't yet know which other problems might come around)... So let me summarize what I know now: - class helper syntax is the followingː ClassHelperName = class helper[(BaseClassHelper)] for ExtendedClass (...) end; BaseClassHelper must be a class helper for the same class. - in "virtual; abstract;" and "override;" after methods of the extended class generate an error, while "dynamic;" and "virtual;" are allowed - "message" is allowed but in the end not accessable - should that be forbidden in mode "objfpc"? - only the first found class helper for a given class is used - class helpers can not be used in forward declarations - class helpers can not extend generic classes - class helpers may not contain destructors - class helpers may contain constructors, but these need to call the inherited parameterless constructor without any argument as first statement (regarding class constructors I need to read the article linked by Jonas) - class helpers hide methods with the same name in the ExtendedClass, but not in derived classes - is this a good behavior? (in the current test implementation a class helper method is only searched if no other identifier is found) Are those assumptions correct so far? Did I miss something we already know? Maybe I should write a wiki page to have the "specification" saved somewhere :) Regards, Sven ___ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
