fpc/tests/test/tgenconstraint1.pp
svenbarth 4adb36e8da Add support for generic type constraints. They are currently only useful to stop specialization of a generic. The parsing of a generic is still too lax and needs to be changed in the future...
symconst.pas:
  + extend "tdefoptions" by a "df_genconstraint" which will be used to mark dummy defs that should mainly satisfy the compiler's type checking without to much changes
symsym.pas:
  + add a class "tgenericconstraintdata" which will hold information about the constraints associated with a specific generic type parameter (designed for future extensions)
  + extend "ttypesym" by a reference to a "tgenericconstraintdata" which is written to the ppu only if needed
symtype.pas:
  + add a pointer to "tderef" as this is needed for the ppu reading/writing code for the "tgenericconstraintdata"
pdecl.pas, types_dec:
  + call "parse_generic_parameters" so that constraints are allowed
pgenutil.pas:
  + extend "generate_specialization" by a "parsedpos" to give in the file position of the first parsed parameter (needed for correct error locations when checking the constraints)
  + add an overloaded call of "generate_specialization" to differentiate between the use cases "first parameter parsed by generate_specialization" and "first parameter parsed by other code"; this also allows to write the "fillchar" for the "parampos" parameter only once ( => otherwise a warning is triggered => error in compilation)
  + extend the "parse_generic_specialization_types" by a "poslist" parameter which will contain the positions of all parsed type parameters (can only be used in the case that all parameters are parsed)
  * move the original code of "parse_generic_specialization_types" to a new procedure "parse_generic_specialization_types_internal" which take an additional "parsedpos" parameter which will be added to the "poslist" before all others; "parse_generic_specialization_types" calls this new procedure with a dummy argument (which won't be used)
  + extend "parse_generic_parameters" by the parsing of generic constraints which constructs correct defs for the parameters and fills in the new "tgenericconstraintdata" object for each parameter (note: the "constructor" constraint is only parsed for Delphi compatibility and basically means the same as a "class" constraint... (it's a relict of Delphi.NET))
  * adjust "insert_generic_parameter_types" as specializations and generics can no longer be differed by whether the type parameters are of type "undefineddef"
pdecsub.pas, parse_proc_head, consume_generic_interface:
  * adjust call to "generate_specialization"
  + add a new function "check_generic_constraints" which is used from within "generate_specialization" to ensure that the given specialization parameters are compatible with the constraints of the generic parameters
ptype.pas:
  * single_type: adjust call to "generate_specialization"
  * read_named_type, expr_type: adjust call to "generate_specialization"
  + write_persistent_type_info: don't write typeinfo for constraints
pexpr.pas, sub_expr:
  * adjust call to "generate_specialization"
* adjusted ppudump, because of added "tdefoptions.df_genconstraint" value

+ added tests for generic constraints
* modified test for class helper inside a generic which extends a class type parameter
+ added test for record helper inside a generic which extends a record type parameter

git-svn-id: trunk@23158 -
2012-12-16 13:44:58 +00:00

79 lines
1.9 KiB
ObjectPascal

{ %NORUN }
{ Extensively test the Delphi compatible constraint syntax }
program tgenconstraint1;
{$ifdef fpc}
{$mode delphi}
{$endif}
{ types used for tests }
uses
ugenconstraints;
type
TTest1TObject = TTest1<TObject>;
// the documentation did say something different here...
//TTest1IInterface = TTest1<IInterface>;
TTest1TTestClass = TTest1<TTestClass>;
TTest2TTestRec = TTest2<TTestRec>;
TTest3TTestClass = TTest3<TTestClass>;
TTest3TTestClass2 = TTest3<TTestClass2>;
{ ToDo }
TTest4TTestClass = TTest4<TTestClass>;
TTest4TTestClass2 = TTest4<TTestClass2>;
TTest5IInterface = TTest5<IInterface>;
TTest5ITest1 = TTest5<ITest1>;
TTest5ITest2 = TTest5<ITest2>;
TTest5TInterfacedObject = TTest5<TInterfacedObject>;
TTest6TTestClass3 = TTest6<TTestClass3>;
TTest6TTestClass4 = TTest6<TTestClass4>;
TTest7TTestClass4 = TTest7<TTestClass4>;
TTest8TTestClass3 = TTest8<TTestClass3>;
TTest8TTestClass4 = TTest8<TTestClass4>;
//TTest8TTestClass5 = TTest8<TTestClass5>;
// TTest9 is the same as TTest8
TTest10TTestClass3 = TTest10<TTestClass3>;
TTest10TTestClass6 = TTest10<TTestClass6>;
// TTest11 is the same as TTest10
TTest12TTestClass = TTest12<TTestClass7>;
TTest13TTestClass = TTest13<TTestClass>;
TTest13TTestClass6 = TTest13<TTestClass2>;
// TTest14 is the same as TTest10
TTest15TTestClass8 = TTest15<TTestClass8>;
TTest16TTestClass3 = TTest16<TTestClass3>;
TTest17ITest1ITest1 = TTest17<ITest1, ITest1>;
TTest17ITestClass3ITest2 = TTest17<TTestClass3, ITest2>;
TTest18ITest1ITest2 = TTest18<ITest1, ITest2>;
TTest18TTestClass3TTestClass5 = TTest18<TTestClass3, TTestClass5>;
TTest18TTestClass4TTestClass4TTestClass4 = TTest18<TTestClass4, TTestClass4>;
TTest19TTestRecTObject = TTest19<TTestRec, TObject>;
TTest20TTestClassTTestClass = TTest20<TTestClass, TTestClass>;
TTest21TObject = TTest21<TObject>;
TTest21TestClass = TTest21<TTestClass>;
begin
end.