[fpc-devel] Re: [fpc-announce] Feature announcement: Type helpers
Gerhard Scholz
gs at g--s.de
Fri Feb 8 00:30:32 CET 2013
Hello,
I tried to compile the example:
type
TLongIntHelper = type helper for LongInt
class procedure Test; static;
end;
class procedure TLongIntHelper.Test;
begin
Writeln('Test');
end;
var
i: LongInt;
begin
i.Test;
$12345678.Test;
LongInt.Test;
end.
Result:
0:25:46,51
G:\ob\syncdirs>ppc386 -vv -al -CioOrt -Cs6000000 -gclt -Mobjfpc -O1 -OpPENTIUM
-Fuu:\ -FuM:\u -FuC:\c\-u -FiC:\c\-u -Fuz:\-u -Fiz:\-u -FuP:\gs\tp55\includes
-Fuf:\-u -Fiu:\ -FiM:\u -FiP:\gs\tp55\includes -Fif:\-u -FE.
thelper
thelper.pas(2,33) Error: Identifier not found "helper"
thelper.pas(2,33) Error: Error in type definition
thelper.pas(2,33) Error: Can't create unique type from this type
thelper.pas(2,33) Fatal: Syntax error, ";" expected but "FOR" found
Fatal: Compilation aborted
The compiler is freshly generated from the SVN
Does the compiler expect special options to invoke the record helper
feature?
Gerhard
----- Original Message -----
From: "Sven Barth" <pascaldragon at googlemail.com>
To: <fpc-announce at lists.freepascal.org>
Cc: <fpc-pascal at lists.freepascal.org>; "FPC developers' list"
<fpc-devel at lists.freepascal.org>
Sent: Wednesday, February 06, 2013 10:49 AM
Subject: [fpc-announce] Feature announcement: Type helpers
> Hello Free Pascal community!
>
> I'm pleased to announce the addition of type helpers which extend the
> existing helper concept with the ability to extend primitive types.
>
> Motivation:
>
> With class and record helpers the possibility was created to extend
> classes and records with types without subclassing the type (which
> wouldn't be possible with records anyway). This allows to add e.g. methods
> to types in units that you can't influence or where you can't influence
> with type is instantiated (e.g. the TStrings descendant used in TMemo).
> Now it is logical to extend this also to other types supported by Pascal,
> but here more driven by the possibility to group methods together and have
> them appear to belong to the primitive type.
>
> While this does not bring the concepts of boxing of managed
> languages/environments like Java and .NET to Pascal it does nevertheless
> look this way.
>
> Syntax:
>
> The declaration of type helpers looks as follows:
>
> TYPENAME = type helper[(BASEHELPER)] for EXTENDEDTYPE
> DECLARATIONS
> end;
>
> Like class and record helpers they support all visibility sections and you
> can define methods, properties and constructors. Inside methods declared
> in the helper "Self" will be of the extended type's type and it's value
> can also be changed.
> Similar to record helpers class methods MUST be declared as static.
>
> Usage:
>
> A type helper is active if it is in scope. This means it must either have
> been declared in the same unit before the code which wants to use the
> helper or it needs to be declared in a used unit. As with class and type
> helpers only one helper for a given type can be active and thus you need
> to keep in mind the scoping rules when using helpers (e.g. the current
> unit is searched in the order implementation section then interface
> section (if the code is in the implementation section) and then the used
> units are searched from right to left and each unit from top to bottom).
>
> In some cases the meaning of a type depends on the compiler settings the
> helper is compiled with. E.g. the type Integer is either a ShortInt or a
> LongInt depending on the current mode (fpc/tp vs. objfpc/delphi) and the
> type String is different depending on the switches {$H+/-} and
> {$modeswitch unicodestring}. This needs to be kept in mind when working
> with these "generic" types. Another special case is the type Extended on
> platforms that don't support that type (and thus it will be defined as
> Double).
> Additionally a type declared as "NewType = type OldType" is considered a
> completly independant type as it is the case with e.g. operator overloads
> as well.
>
> If a helper for the type is in scope you can simply invoke it's methods or
> properties like you'd do on classes or records. Let's suppose we have a
> helper with method "ToString: String" for the type LongInt in scope then
> it will look like this:
>
> === example begin ===
>
> var
> i: LongInt;
> begin
> Writeln(i.ToString);
> end.
>
> === example end ===
>
> Additionally to invoking type helpers on variables they can also be used
> on constants though special care needs to be taken that the correct type
> is used. E.g. the constant "200" will be handled as a "Byte" whereas "20"
> will be handled as "SmallInt". Also the type of string constants depends
> on the current mode switch (especially {$H+/-} and {$modeswitch
> unicodestring}) and also the content of the string. E.g. in case of
> "{$mode objfpc}{$H+}" a string containing unicode characters will be
> handled as a UnicodeString constant and thus only helpers for
> UnicodeString will apply.
>
> For the following example let's assume the helper from the previous
> example is in scope again:
>
> === example begin ===
>
> begin
> Writeln($12345678.ToString);
> end.
>
> === example end ===
>
> Additionally addresses (e.g. "@i") (type: Pointer) and the built in
> constants "True" (type: Boolean), "False" (type: Boolean) and "Nil" (type:
> Pointer) are allowed as well. Please note that in the case of typed
> addresses also the untyped pointer type will be used, because a
> corresponding typename might not be available to the current unit (and
> thus the helper could not be found). Constants that can't be used with
> type helpers are set and array constructors.
>
> Class methods (and properties) can be either used on variables or
> constants, but also on the type name itself:
>
> === example begin ===
>
> type
> TLongIntHelper = type helper for LongInt
> class procedure Test; static;
> end;
>
> class procedure TLongIntHelper.Test;
> begin
> Writeln('Test');
> end;
>
> var
> i: LongInt;
> begin
> i.Test;
> $12345678.Test;
> LongInt.Test;
> end.
>
> === example end ===
>
> Supported types:
>
> There is a restrictions on the type which can be extended. Basically every
> primitive type is allowed besides the following:
>
> * file types (TextFile, file of ...)
> * procedural variables
>
> Of course types like records, classes, Objective C classes, C++ classes,
> objects and interfaces are forbidden as well.
>
> Viewed from the other perspective this means that the following types are
> allowed:
>
> * ordinal types
> * string types (including char types)
> * set and enum types
> * array types
> * boolean types
> * Variant
> * floating point types
> * pointer types
>
> Delphi compatibility:
>
> This feature was introduced by Delphi XE3, but instead of using the more
> logical "type helper" syntax they added support for primitive types to the
> "record helper" one. Thus to keep Delphi compatibility this is also the
> syntax used in mode Delphi. Also in non Delphi modes inheritance for
> helper types is supported.
>
> Future developments:
>
> Add support for more types, especially interface and object types. They
> will either be added as class helpers or as "object helper" and "interface
> helper" (as objects and interfaces support inheritance the scoping rules
> inside the helper will resemble class helpers more than record/type
> helpers).
>
> Allow that multiple helpers are active for one type at a single time. This
> is one of the main restrictions of the current helper implementation. For
> this corresponding lookup rules need to be defined and the feature will be
> added as a modeswitch (maybe by default enabled in mode objfpc).
>
> Add support for helpers to the JVM target. The most likely implementation
> approach is to pass the "Self" value as an additional parameter and treat
> the methods otherwise as static ones (like is done in .NET for helper
> methods).
>
> Regards,
> Sven
> _______________________________________________
> fpc-announce maillist - fpc-announce at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-announce
More information about the fpc-devel
mailing list