Difference between revisions of "pas2js Generics"

From Free Pascal wiki
Jump to navigationJump to search
Line 1: Line 1:
 
=Overview=
 
=Overview=
 +
 +
Pas2js will support FPC and Delphi like generics.
  
 
==Working==
 
==Working==
Line 11: Line 13:
 
* generic class
 
* generic class
 
** specialize in ancestor type
 
** specialize in ancestor type
** forward generic class (FPC does not support it yet)
+
** forward generic class (FPC 3.3.1 does not support it yet)
 
** enumtype inside generic is not propagated
 
** enumtype inside generic is not propagated
 
* generic external class
 
* generic external class
 
* generic array
 
* generic array
 +
* generic interface
 +
* generic procedural type
 +
* Delphi type overload, e.g. ''type TArr = array of word; TArr<T> = array of T; TArr<T,S> = record i:T; j:S end;''
 +
* anonymous type in specialize: ''TBird<array of word>''
 
* record/class field
 
* record/class field
 
* property
 
* property
 
* method (not confused with generic method)
 
* method (not confused with generic method)
 +
** Delphi: implementation must repeat type params, must omit constraints
 +
** FPC: implementation must not repeat type params
 
* for-loop, if-then-else, repeat-until, while-do, try-finally, try-except, case-of
 
* for-loop, if-then-else, repeat-until, while-do, try-finally, try-except, case-of
 
* some assignments
 
* some assignments
Line 25: Line 33:
 
** keyword ''record'', keyword ''class'' checked at specialization
 
** keyword ''record'', keyword ''class'' checked at specialization
 
** class type checked at specialization
 
** class type checked at specialization
 +
* constraints:
 +
** "class", "record": test if param fits
 +
** class type: test if param fits
 +
** list of interface types: test if param fits
 +
** forward class must repeat constraints
 +
* statements:
 +
** specialize (cloning) all kinds of statements and expressions
 +
** inline specialize expression, e.g. ''TList<word>.Create''
 +
*** Delphi: TFoo<Integer>.Create
 +
*** FPC: specialize TFoo<Integer>.Create
  
 
==ToDos==
 
==ToDos==
  
* Delphi type overload, e.g. type TArr = array of word; TArr<T> = array of T; TArr<T,S> = record i:T; j:S end;
 
 
* cascaded specialize: TBird<word>.TWing<byte>
 
* cascaded specialize: TBird<word>.TWing<byte>
 
* nested specialize: TBird<TWing<byte>>
 
* nested specialize: TBird<TWing<byte>>
* anonymous type in specialize: TBird<array of word>
 
 
* generic class:
 
* generic class:
 
** default classname "TTest<System.Longint>"
 
** default classname "TTest<System.Longint>"
Line 38: Line 54:
 
** members can refer to itself without parameters
 
** members can refer to itself without parameters
 
** nested generic: allowed by Delphi, not allowed by FPC
 
** nested generic: allowed by Delphi, not allowed by FPC
*** Delphi: must repeat type params, can omit constraints
 
*** FPC: must not repeat type params
 
* generic interface:
 
 
* generic static array: Note: delphi wiki says "no static arrays", but 10.3 compiles it, see http://docwiki.embarcadero.com/RADStudio/Rio/en/Declaring_Generics
 
* generic static array: Note: delphi wiki says "no static arrays", but 10.3 compiles it, see http://docwiki.embarcadero.com/RADStudio/Rio/en/Declaring_Generics
* generic procedural type:
 
 
* generic function (aka parametrized method):
 
* generic function (aka parametrized method):
 
** Delphi does not allow global generic functions, only generic methods
 
** Delphi does not allow global generic functions, only generic methods
 
** methods: virtual, message, constructor and destructors cannot have type parameters
 
** methods: virtual, message, constructor and destructors cannot have type parameters
 
* constraints:
 
* constraints:
** "class", "record", "constructor" (class+default constructor, can be combined with class)
+
** "constructor" (class+default constructor, can be combined with class)
** multiple interface types
 
 
** one class type (Delphi: not TObject)
 
** one class type (Delphi: not TObject)
** forward class must repeat constraints
 
 
* specialize method:
 
* specialize method:
 
** explicitly specifying  Fly<word>(aWord)
 
** explicitly specifying  Fly<word>(aWord)
Line 57: Line 67:
 
* Statements:
 
* Statements:
 
** for-in, enumerators
 
** for-in, enumerators
** specialize (cloning) all kinds of statements and expressions
 
 
** inline specialization
 
** inline specialization
*** Delphi: TFoo<Integer>.Create
 
*** FPC: specialize TFoo<Integer>.Create
 
 
** T is TFoo<Integer>
 
** T is TFoo<Integer>
 
** T as TFoo<Integer>
 
** T as TFoo<Integer>

Revision as of 15:34, 26 August 2019

Overview

Pas2js will support FPC and Delphi like generics.

Working

  • generic record
  • specialize:
    • ObjFPC: type TFoo = specialize TGen<word>;
    • Delphi: type TFoo = TGen<word>;
    • ObjFPC anonymous: var r: specialize TBird<word>;
    • Delphi: anonymous var r: TBird<word>;
  • generic class
    • specialize in ancestor type
    • forward generic class (FPC 3.3.1 does not support it yet)
    • enumtype inside generic is not propagated
  • generic external class
  • generic array
  • generic interface
  • generic procedural type
  • Delphi type overload, e.g. type TArr = array of word; TArr<T> = array of T; TArr<T,S> = record i:T; j:S end;
  • anonymous type in specialize: TBird<array of word>
  • record/class field
  • property
  • method (not confused with generic method)
    • Delphi: implementation must repeat type params, must omit constraints
    • FPC: implementation must not repeat type params
  • for-loop, if-then-else, repeat-until, while-do, try-finally, try-except, case-of
  • some assignments
  • primitive expression like identifiers and constants
  • operators: +, -
  • constraints:
    • keyword record, keyword class checked at specialization
    • class type checked at specialization
  • constraints:
    • "class", "record": test if param fits
    • class type: test if param fits
    • list of interface types: test if param fits
    • forward class must repeat constraints
  • statements:
    • specialize (cloning) all kinds of statements and expressions
    • inline specialize expression, e.g. TList<word>.Create
      • Delphi: TFoo<Integer>.Create
      • FPC: specialize TFoo<Integer>.Create

ToDos

  • cascaded specialize: TBird<word>.TWing<byte>
  • nested specialize: TBird<TWing<byte>>
  • generic class:
    • default classname "TTest<System.Longint>"
    • pas2js classname "TTest$G1" and overloads
    • descendants cannot refer to type parameters of ancestors
    • members can refer to itself without parameters
    • nested generic: allowed by Delphi, not allowed by FPC
  • generic static array: Note: delphi wiki says "no static arrays", but 10.3 compiles it, see http://docwiki.embarcadero.com/RADStudio/Rio/en/Declaring_Generics
  • generic function (aka parametrized method):
    • Delphi does not allow global generic functions, only generic methods
    • methods: virtual, message, constructor and destructors cannot have type parameters
  • constraints:
    • "constructor" (class+default constructor, can be combined with class)
    • one class type (Delphi: not TObject)
  • specialize method:
    • explicitly specifying Fly<word>(aWord)
    • automatic inferring types Fly(aWord), $modeswitch implicitfunctionspecialization MyProc(1) calls MyProc<T>(a: T)
  • specialized proc types can assign normal proc
  • Statements:
    • for-in, enumerators
    • inline specialization
    • T is TFoo<Integer>
    • T as TFoo<Integer>
    • TFoo<Integer>(expr)
    • "obj is T": allowed with constraint "class" or class type
    • typecast T(): allowed with constraint "class" or class type
    • typeinfo(T)
    • using implementation function in generic function:
      • Delphi: Error: Method of parameterized type declared in interface section must not use local symbol '%s'
      • FPC: Error: Global Generic template references static symtable
    • anInt:=GenericVar
      • Delphi: always Error: Incompatible types: 'Integer' and 'T'
      • FPC: allowed for valid combinations -> operators are checked on specialization, Note: because of implementation cross uses, check must be delayed until used unit implementation is complete
    • call
      • Delphi: must fit the constraint. For example without constraint it only fits untyped args.
      • FPC: if only one function in scope preselect it, overloads are selected by constraints alone. Later checked by specialization.