pas2js Generics
From Free Pascal wiki
Jump to navigationJump to searchOverview
Pas2js will support FPC and Delphi like generics.
The next goal is test running TList methods and fix bugs.
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 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 interface
- generic procedural type
- specialized proc types can assign normal proc
- 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>
- nested specialize: TBird<TWing<byte>>
- 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, class, constructor checked at specialization
- class type checked at specialization
- constraints:
- "class", "record", "constructor": test if param fits
- class type: test if param fits
- list of interface types: test if param fits
- forward class must repeat constraints
- Delphi does not allow TObject as constraint. pas2js allows it, because it has other root classes.
- 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
- "obj is T": allowed with constraint "class" or class type
- typecast T(): allowed with constraint "class" or class type
- 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
- Pas2js: allowed
ToDos
- nested generic type: allowed by Delphi, not allowed by FPC
- cascaded specialize: TBird<word>.TWing<byte>
- constraint refers to prior template name: type TBird<X, Y: TAnt<X>> = record a: X; b: Y; end;
- generic class:
- default classname "TTest<System.Longint>"
- pas2js classname "TTest$G1" and overloads
- Delphi: descendants cannot refer to type parameters of ancestors
- members can refer to itself without parameters
- 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
- specialize method:
- explicitly specifying Fly<word>(aWord)
- automatic inferring types Fly(aWord), $modeswitch implicitfunctionspecialization MyProc(1) calls MyProc<T>(a: T)
- Statements:
- for-in T
- T is TFoo<Integer>
- T as TFoo<Integer>
- TFoo<Integer>(expr)
- typeinfo(T)
- 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.
- nicer error messages
- instead of TList$G1 write TList<word>
- write a hint where it was specialized
- filer
- optimization: reuse specialized functions