tcgenerics.pp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. unit tcgenerics;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fpcunit, pastree, testregistry, pscanner, tctypeparser;
  6. Type
  7. { TTestGenerics }
  8. TTestGenerics = Class(TBaseTestTypeParser)
  9. Published
  10. Procedure TestObjectGenerics;
  11. Procedure TestRecordGenerics;
  12. Procedure TestArrayGenerics;
  13. Procedure TestSpecializationDelphi;
  14. Procedure TestDeclarationDelphi;
  15. Procedure TestDeclarationDelphiSpecialize;
  16. Procedure TestMethodImplementation;
  17. Procedure TestInlineSpecializationInArgument;
  18. Procedure TestSpecializeNested;
  19. Procedure TestInlineSpecializeInStatement;
  20. end;
  21. implementation
  22. procedure TTestGenerics.TestObjectGenerics;
  23. begin
  24. Add([
  25. 'Type',
  26. 'Generic TSomeClass<T> = Object',
  27. ' b : T;',
  28. 'end;',
  29. '']);
  30. ParseDeclarations;
  31. end;
  32. procedure TTestGenerics.TestRecordGenerics;
  33. begin
  34. Add([
  35. 'Type',
  36. ' Generic TSome<T> = Record',
  37. ' b : T;',
  38. ' end;',
  39. '']);
  40. ParseDeclarations;
  41. end;
  42. procedure TTestGenerics.TestArrayGenerics;
  43. begin
  44. Add([
  45. 'Type',
  46. ' Generic TSome<T> = array of T;',
  47. '']);
  48. ParseDeclarations;
  49. end;
  50. procedure TTestGenerics.TestSpecializationDelphi;
  51. begin
  52. ParseType('TFPGList<integer>',TPasSpecializeType,'');
  53. end;
  54. procedure TTestGenerics.TestDeclarationDelphi;
  55. Var
  56. T : TPasClassType;
  57. begin
  58. Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
  59. Source.Add('Type');
  60. Source.Add(' TSomeClass<T,T2> = Class(TObject)');
  61. Source.Add(' b : T;');
  62. Source.Add(' b2 : T2;');
  63. Source.Add('end;');
  64. ParseDeclarations;
  65. AssertNotNull('have generic definition',Declarations.Classes);
  66. AssertEquals('have generic definition',1,Declarations.Classes.Count);
  67. AssertEquals('Pascal class',TPasClassType,TObject(Declarations.Classes[0]).ClassType);
  68. T:=TPasClassType(Declarations.Classes[0]);
  69. AssertNotNull('have generic templates',T.GenericTemplateTypes);
  70. AssertEquals('2 template types',2,T.GenericTemplateTypes.Count);
  71. AssertSame('Parent 0 is class',T,TPasElement(T.GenericTemplateTypes[0]).Parent);
  72. AssertSame('Parent 1 is class',T,TPasElement(T.GenericTemplateTypes[1]).Parent);
  73. end;
  74. procedure TTestGenerics.TestDeclarationDelphiSpecialize;
  75. Var
  76. T : TPasClassType;
  77. begin
  78. Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
  79. Source.Add('Type');
  80. Source.Add(' TSomeClass<T,T2> = Class(TSomeGeneric<Integer,Integer>)');
  81. Source.Add(' b : T;');
  82. Source.Add(' b2 : T2;');
  83. Source.Add('end;');
  84. ParseDeclarations;
  85. AssertNotNull('have generic definition',Declarations.Classes);
  86. AssertEquals('have generic definition',1,Declarations.Classes.Count);
  87. AssertEquals('Pascal class',TPasClassType,TObject(Declarations.Classes[0]).ClassType);
  88. T:=TPasClassType(Declarations.Classes[0]);
  89. AssertEquals('Name is correct','TSomeClass',T.Name);
  90. AssertNotNull('have generic templates',T.GenericTemplateTypes);
  91. AssertEquals('2 template types',2,T.GenericTemplateTypes.Count);
  92. AssertSame('Parent 0 is class',T,TPasElement(T.GenericTemplateTypes[0]).Parent);
  93. AssertSame('Parent 1 is class',T,TPasElement(T.GenericTemplateTypes[1]).Parent);
  94. end;
  95. procedure TTestGenerics.TestMethodImplementation;
  96. begin
  97. With source do
  98. begin
  99. Add('unit afile;');
  100. Add('{$MODE DELPHI}');
  101. Add('interface');
  102. Add('type');
  103. Add(' TTest<T> = object');
  104. Add(' procedure foo(v:T);');
  105. Add(' end;');
  106. Add('implementation');
  107. Add('procedure TTest<T>.foo;');
  108. Add('begin');
  109. Add('end;');
  110. end;
  111. ParseModule;
  112. end;
  113. procedure TTestGenerics.TestInlineSpecializationInArgument;
  114. begin
  115. With source do
  116. begin
  117. Add('unit afile;');
  118. Add('{$MODE DELPHI}');
  119. Add('interface');
  120. Add('type');
  121. Add(' TFoo=class');
  122. Add(' procedure foo(var Node:TSomeGeneric<TBoundingBox>;const index:Integer);');
  123. Add(' end;');
  124. Add('implementation');
  125. end;
  126. ParseModule;
  127. end;
  128. procedure TTestGenerics.TestSpecializeNested;
  129. begin
  130. Add([
  131. 'Type',
  132. ' generic TSomeClass<A,B> = class(specialize TOther<A,specialize TAnother<B>>) end;',
  133. '']);
  134. ParseDeclarations;
  135. end;
  136. procedure TTestGenerics.TestInlineSpecializeInStatement;
  137. begin
  138. Add([
  139. 'begin',
  140. ' vec:=TVector<double>.create;',
  141. ' b:=a<b;',
  142. ' t:=a<b.c<d,e.f>>;',
  143. '']);
  144. ParseModule;
  145. end;
  146. initialization
  147. RegisterTest(TTestGenerics);
  148. end.