/packages/fcl-passrc/tests/tctypeparser.pas

https://github.com/slibre/freepascal · Pascal · 2839 lines · 2411 code · 413 blank · 15 comment · 16 complexity · a1f7e5d4fb1b8933d72bf741719ace76 MD5 · raw file

Large files are truncated click here to view the full file

  1. unit tctypeparser;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fpcunit, pastree, pscanner, pparser,
  6. tcbaseparser, testregistry;
  7. type
  8. { TBaseTestTypeParser }
  9. TBaseTestTypeParser= Class(TTestParser)
  10. private
  11. FType : TPasType;
  12. FHint : string;
  13. FErrorSource : String;
  14. Protected
  15. Function ParseType(ASource : String; ATypeClass : TClass;Const AHint : String = '') : TPasType; virtual; overload;
  16. Procedure AssertParseTypeError(ASource : String);
  17. Property TheType : TPasType Read FType;
  18. Property Hint : string Read FHint Write FHint;
  19. procedure SetUp; override;
  20. Procedure TearDown; override;
  21. end;
  22. { TTestTypeParser }
  23. TTestTypeParser = Class(TBaseTestTypeParser)
  24. private
  25. Protected
  26. Procedure DoTestAliasType(Const AnAliasType : String; Const AHint : String);
  27. procedure DoTestStringType(const AnAliasType: String; const AHint: String);
  28. procedure DoTypeError(Const AMsg,ASource : string);
  29. Procedure DoParseError;
  30. Procedure DoParsePointer(Const ASource : String; Const AHint : String; ADestType : TClass = Nil);
  31. Procedure DoParseArray(Const ASource : String; Const AHint : String; ADestType : TClass = Nil);
  32. Procedure DoParseEnumerated(Const ASource : String; Const AHint : String; ACount : integer);
  33. Procedure DoTestFileType(Const AType : String; Const AHint : String; ADestType : TClass = Nil);
  34. Procedure DoTestRangeType(Const AStart,AStop,AHint : String);
  35. Procedure DoParseSimpleSet(Const ASource : String; Const AHint : String);
  36. Procedure DoParseComplexSet(Const ASource : String; Const AHint : String);
  37. procedure DoParseRangeSet(const ASource: String; const AHint: String);
  38. Procedure DoTestComplexSet;
  39. Procedure DoTestClassOf(Const AHint : string);
  40. Published
  41. Procedure TestAliasType;
  42. Procedure TestCrossUnitAliasType;
  43. Procedure TestAliasTypeDeprecated;
  44. Procedure TestAliasTypePlatform;
  45. Procedure TestSimpleTypeByte;
  46. Procedure TestSimpleTypeByteDeprecated;
  47. Procedure TestSimpleTypeBytePlatform;
  48. Procedure TestSimpleTypeBoolean;
  49. Procedure TestSimpleTypeBooleanDeprecated;
  50. Procedure TestSimpleTypeBooleanPlatform;
  51. Procedure TestSimpleTypeChar;
  52. Procedure TestSimpleTypeCharDeprecated;
  53. Procedure TestSimpleTypeCharPlatform;
  54. Procedure TestSimpleTypeInteger;
  55. Procedure TestSimpleTypeIntegerDeprecated;
  56. Procedure TestSimpleTypeIntegerPlatform;
  57. Procedure TestSimpleTypeInt64;
  58. Procedure TestSimpleTypeInt64Deprecated;
  59. Procedure TestSimpleTypeInt64Platform;
  60. Procedure TestSimpleTypeLongInt;
  61. Procedure TestSimpleTypeLongIntDeprecated;
  62. Procedure TestSimpleTypeLongIntPlatform;
  63. Procedure TestSimpleTypeLongWord;
  64. Procedure TestSimpleTypeLongWordDeprecated;
  65. Procedure TestSimpleTypeLongWordPlatform;
  66. Procedure TestSimpleTypeDouble;
  67. Procedure TestSimpleTypeDoubleDeprecated;
  68. Procedure TestSimpleTypeDoublePlatform;
  69. Procedure TestSimpleTypeShortInt;
  70. Procedure TestSimpleTypeShortIntDeprecated;
  71. Procedure TestSimpleTypeShortIntPlatform;
  72. Procedure TestSimpleTypeSmallInt;
  73. Procedure TestSimpleTypeSmallIntDeprecated;
  74. Procedure TestSimpleTypeSmallIntPlatform;
  75. Procedure TestSimpleTypeString;
  76. Procedure TestSimpleTypeStringDeprecated;
  77. Procedure TestSimpleTypeStringPlatform;
  78. Procedure TestSimpleTypeStringSize;
  79. Procedure TestSimpleTypeStringSizeIncomplete;
  80. Procedure TestSimpleTypeStringSizeWrong;
  81. Procedure TestSimpleTypeStringSizeDeprecated;
  82. Procedure TestSimpleTypeStringSizePlatform;
  83. Procedure TestSimpleTypeWord;
  84. Procedure TestSimpleTypeWordDeprecated;
  85. Procedure TestSimpleTypeWordPlatform;
  86. Procedure TestSimpleTypeQWord;
  87. Procedure TestSimpleTypeQWordDeprecated;
  88. Procedure TestSimpleTypeQWordPlatform;
  89. Procedure TestSimpleTypeCardinal;
  90. Procedure TestSimpleTypeCardinalDeprecated;
  91. Procedure TestSimpleTypeCardinalPlatform;
  92. Procedure TestSimpleTypeWideChar;
  93. Procedure TestSimpleTypeWideCharDeprecated;
  94. Procedure TestSimpleTypeWideCharPlatform;
  95. Procedure TestPointerSimple;
  96. procedure TestPointerSimpleDeprecated;
  97. procedure TestPointerSimplePlatform;
  98. Procedure TestStaticArray;
  99. procedure TestStaticArrayDeprecated;
  100. procedure TestStaticArrayPlatform;
  101. Procedure TestStaticArrayPacked;
  102. Procedure TestStaticArrayTypedIndex;
  103. Procedure TestDynamicArray;
  104. Procedure TestSimpleEnumerated;
  105. Procedure TestSimpleEnumeratedDeprecated;
  106. Procedure TestSimpleEnumeratedPlatform;
  107. Procedure TestAssignedEnumerated;
  108. Procedure TestAssignedEnumeratedDeprecated;
  109. Procedure TestAssignedEnumeratedPlatform;
  110. Procedure TestFileType;
  111. Procedure TestFileTypeDeprecated;
  112. Procedure TestFileTypePlatform;
  113. Procedure TestRangeType;
  114. Procedure TestRangeTypeDeprecated;
  115. Procedure TestRangeTypePlatform;
  116. Procedure TestIdentifierRangeType;
  117. Procedure TestIdentifierRangeTypeDeprecated;
  118. Procedure TestIdentifierRangeTypePlatform;
  119. Procedure TestNegativeIdentifierRangeType;
  120. Procedure TestSimpleSet;
  121. Procedure TestSimpleSetDeprecated;
  122. Procedure TestSimpleSetPlatform;
  123. Procedure TestComplexSet;
  124. Procedure TestComplexSetDeprecated;
  125. Procedure TestComplexSetPlatform;
  126. Procedure TestRangeSet;
  127. Procedure TestRangeSetDeprecated;
  128. Procedure TestRangeSetPlatform;
  129. Procedure TestClassOf;
  130. Procedure TestClassOfDeprecated;
  131. Procedure TestClassOfPlatform;
  132. Procedure TestReferenceAlias;
  133. Procedure TestReferenceSet;
  134. Procedure TestReferenceClassOf;
  135. Procedure TestReferenceFile;
  136. Procedure TestReferenceArray;
  137. Procedure TestReferencePointer;
  138. end;
  139. { TTestRecordTypeParser }
  140. TTestRecordTypeParser= Class(TBaseTestTypeParser)
  141. private
  142. Function GetField(AIndex : Integer; R : TPasRecordType) : TPasVariable;
  143. Function GetField(AIndex : Integer; R : TPasVariant) : TPasVariable;
  144. function GetF(AIndex: Integer): TPasVariable;
  145. function GetR: TPasRecordType;
  146. Function GetVariant(AIndex : Integer; R : TPasRecordType) : TPasVariant;
  147. function GetV(AIndex: Integer): TPasVariant;
  148. Protected
  149. Procedure TestFields(Const Fields : Array of string; AHint : String; HaveVariant : Boolean = False);
  150. procedure AssertVariantSelector(AName, AType: string);
  151. procedure AssertField1(Hints: TPasMemberHints);
  152. procedure AssertField2(Hints: TPasMemberHints);
  153. procedure AssertVariant1(Hints: TPasMemberHints);
  154. procedure AssertVariant1(Hints: TPasMemberHints; VariantLabels : Array of string);
  155. procedure AssertVariant2(Hints: TPasMemberHints);
  156. procedure AssertVariant2(Hints: TPasMemberHints; VariantLabels : Array of string);
  157. procedure AssertOneIntegerField(Hints: TPasMemberHints);
  158. procedure AssertTwoIntegerFields(Hints1, Hints2: TPasMemberHints);
  159. procedure AssertRecordField(AIndex: Integer;Hints: TPasMemberHints);
  160. procedure AssertRecordVariant(AIndex: Integer;Hints: TPasMemberHints; VariantLabels : Array of string);
  161. Procedure AssertRecordVariantVariant(AIndex: Integer;Const AFieldName,ATypeName: string;Hints: TPasMemberHints; VariantLabels : Array of string);
  162. Procedure DoTestEmpty(Const AHint : String);
  163. procedure DoTestDeprecatedVariantNoStorage(Const AHint : string);
  164. procedure DoTestDeprecatedVariantStorage(Const AHint : string);
  165. procedure DoTestVariantNoStorage(Const AHint : string);
  166. procedure DoTestVariantStorage(Const AHint : string);
  167. procedure DoTestTwoVariantsNoStorage(Const AHint : string);
  168. procedure DoTestTwoVariantsStorage(Const AHint : string);
  169. procedure DoTestTwoVariantsFirstDeprecatedStorage(Const AHint : string);
  170. procedure DoTestTwoVariantsSecondDeprecatedStorage(Const AHint : string);
  171. Procedure DoTestVariantTwoLabels(Const AHint : string);
  172. Procedure DoTestTwoVariantsTwoLabels(Const AHint : string);
  173. procedure DoTestVariantNestedRecord(Const AHint : string);
  174. procedure DoTestVariantNestedVariant(Const AHint : string);
  175. procedure DoTestVariantNestedVariantFirstDeprecated(Const AHint : string);
  176. procedure DoTestVariantNestedVariantSecondDeprecated(const AHint: string);
  177. procedure DoTestVariantNestedVariantBothDeprecated(const AHint: string);
  178. Property TheRecord : TPasRecordType Read GetR;
  179. Property Field1 : TPasVariable Index 0 Read GetF;
  180. Property Field2 : TPasVariable Index 1 Read GetF;
  181. Property Variant1 : TPasVariant Index 0 Read GetV;
  182. Property Variant2 : TPasVariant Index 1 Read GetV;
  183. Published
  184. Procedure TestEmpty;
  185. Procedure TestEmptyDeprecated;
  186. Procedure TestEmptyPlatform;
  187. Procedure TestOneField;
  188. Procedure TestOneFieldDeprecated;
  189. Procedure TestOneFieldPlatform;
  190. Procedure TestOneFieldSemicolon;
  191. Procedure TestOneFieldSemicolonDeprecated;
  192. Procedure TestOneFieldSemicolonPlatform;
  193. Procedure TestOneDeprecatedField;
  194. Procedure TestOneDeprecatedFieldDeprecated;
  195. Procedure TestOneDeprecatedFieldPlatform;
  196. Procedure TestOnePlatformField;
  197. Procedure TestOnePlatformFieldDeprecated;
  198. Procedure TestOnePlatformFieldPlatform;
  199. Procedure TestTwoFields;
  200. Procedure TestTwoFieldDeprecated;
  201. Procedure TestTwoFieldPlatform;
  202. Procedure TestTwoFieldsFirstDeprecated;
  203. Procedure TestTwoFieldsFirstDeprecatedDeprecated;
  204. Procedure TestTwoFieldsFirstDeprecatedPlatform;
  205. Procedure TestTwoFieldsSecondDeprecated;
  206. Procedure TestTwoFieldsSecondDeprecatedDeprecated;
  207. Procedure TestTwoFieldsSecondDeprecatedPlatform;
  208. Procedure TestTwoFieldsBothDeprecated;
  209. Procedure TestTwoFieldsBothDeprecatedDeprecated;
  210. Procedure TestTwoFieldsBothDeprecatedPlatform;
  211. Procedure TestTwoFieldsCombined;
  212. Procedure TestTwoFieldsCombinedDeprecated;
  213. Procedure TestTwoFieldsCombinedPlatform;
  214. Procedure TestTwoDeprecatedFieldsCombined;
  215. Procedure TestTwoDeprecatedFieldsCombinedDeprecated;
  216. Procedure TestTwoDeprecatedFieldsCombinedPlatform;
  217. Procedure TestNested;
  218. Procedure TestNestedDeprecated;
  219. Procedure TestNestedPlatform;
  220. procedure TestNestedSemicolon;
  221. procedure TestNestedSemicolonDeprecated;
  222. procedure TestNestedSemicolonPlatform;
  223. procedure TestNestedFirst;
  224. procedure TestNestedFirstDeprecated;
  225. procedure TestNestedFirstPlatform;
  226. Procedure TestDeprecatedNested;
  227. Procedure TestDeprecatedNestedDeprecated;
  228. Procedure TestDeprecatedNestedPlatform;
  229. procedure TestDeprecatedNestedFirst;
  230. procedure TestDeprecatedNestedFirstDeprecated;
  231. procedure TestDeprecatedNestedFirstPlatform;
  232. Procedure TestVariantNoStorage;
  233. procedure TestVariantNoStorageDeprecated;
  234. procedure TestVariantNoStoragePlatform;
  235. Procedure TestVariantStorage;
  236. procedure TestVariantStorageDeprecated;
  237. procedure TestVariantStoragePlatform;
  238. Procedure TestDeprecatedVariantNoStorage;
  239. procedure TestDeprecatedVariantNoStorageDeprecated;
  240. procedure TestDeprecatedVariantNoStoragePlatform;
  241. Procedure TestDeprecatedVariantStorage;
  242. procedure TestDeprecatedVariantStorageDeprecated;
  243. procedure TestDeprecatedVariantStoragePlatform;
  244. Procedure TestTwoVariantsNoStorage;
  245. procedure TestTwoVariantsNoStorageDeprecated;
  246. procedure TestTwoVariantsNoStoragePlatform;
  247. Procedure TestTwoVariantsStorage;
  248. procedure TestTwoVariantsStorageDeprecated;
  249. procedure TestTwoVariantsStoragePlatform;
  250. Procedure TestTwoVariantsFirstDeprecatedStorage;
  251. procedure TestTwoVariantsFirstDeprecatedStorageDeprecated;
  252. procedure TestTwoVariantsFirstDeprecatedStoragePlatform;
  253. Procedure TestTwoVariantsSecondDeprecatedStorage;
  254. procedure TestTwoVariantsSecondDeprecatedStorageDeprecated;
  255. procedure TestTwoVariantsSecondDeprecatedStoragePlatform;
  256. Procedure TestVariantTwoLabels;
  257. Procedure TestVariantTwoLabelsDeprecated;
  258. Procedure TestVariantTwoLabelsPlatform;
  259. Procedure TestTwoVariantsTwoLabels;
  260. Procedure TestTwoVariantsTwoLabelsDeprecated;
  261. Procedure TestTwoVariantsTwoLabelsPlatform;
  262. Procedure TestVariantNestedRecord;
  263. Procedure TestVariantNestedRecordDeprecated;
  264. Procedure TestVariantNestedRecordPlatform;
  265. Procedure TestVariantNestedVariant;
  266. Procedure TestVariantNestedVariantDeprecated;
  267. Procedure TestVariantNestedVariantPlatForm;
  268. Procedure TestVariantNestedVariantFirstDeprecated;
  269. Procedure TestVariantNestedVariantFirstDeprecatedDeprecated;
  270. Procedure TestVariantNestedVariantFirstDeprecatedPlatform;
  271. Procedure TestVariantNestedVariantSecondDeprecated;
  272. Procedure TestVariantNestedVariantSecondDeprecatedDeprecated;
  273. Procedure TestVariantNestedVariantSecondDeprecatedPlatform;
  274. Procedure TestVariantNestedVariantBothDeprecated;
  275. Procedure TestVariantNestedVariantBothDeprecatedDeprecated;
  276. Procedure TestVariantNestedVariantBothDeprecatedPlatform;
  277. end;
  278. { TTestProcedureTypeParser }
  279. TCallingConventionTest = Procedure (CC : TCallingConvention;Const AHint : String) of object;
  280. TTestProcedureTypeParser = Class(TBaseTestTypeParser)
  281. Private
  282. FProc : TPasProcedureType;
  283. procedure CheckArrayOfConstArgument(Aindex: Integer; Ac: TArgumentAccess);
  284. Protected
  285. procedure DoTestFunction(CC: TCallingConvention; const AHint: String);
  286. procedure DoTestFunctionOfObject(CC: TCallingConvention; const AHint: String);
  287. procedure DoTestFunctionOneArg(CC: TCallingConvention; const AHint: String);
  288. procedure DoTestFunctionOneArgOfObject(CC: TCallingConvention; const AHint: String);
  289. procedure DoTestProcedureOfObject(CC: TCallingConvention; const AHint: String);
  290. procedure DoTestProcedureOfObjectOneArg(CC: TCallingConvention; const AHint: String);
  291. procedure DoTestProcedureIsNested(CC: TCallingConvention; const AHint: String);
  292. procedure DoTestProcedureIsNestedOneArg(CC: TCallingConvention; const AHint: String);
  293. procedure CheckOpenArrayArgument(Ac: TArgumentAccess);
  294. procedure DoTestProcedureArrayOfConst(CC: TCallingConvention; const AHint: String);
  295. procedure DoTestProcedureOpenArray(CC: TCallingConvention; const AHint: String);
  296. procedure DoTestProcedureConstOpenArray(CC: TCallingConvention; const AHint: String);
  297. procedure DoTestProcedureVarOpenArray(CC: TCallingConvention; const AHint: String);
  298. procedure DoTestProcedureOutOpenArray(CC: TCallingConvention; const AHint: String);
  299. procedure DoTestProcedureOneArgDefault(CC: TCallingConvention;const AHint: String);
  300. procedure DoTestProcedureOneArgDefaultExpr(CC: TCallingConvention;const AHint: String);
  301. procedure DoTestProcedureOneArgDefaultSet(CC: TCallingConvention;const AHint: String);
  302. procedure DoTestProcedureOneConstArgDefault(CC: TCallingConvention; const AHint: String);
  303. procedure DoTestProcedureOneVarArgDefault(CC: TCallingConvention; const AHint: String);
  304. procedure DoTestProcedureOneOutArgDefault(CC: TCallingConvention; const AHint: String);
  305. function CheckArgument(AIndex : Integer; Const AName,ATypeName : String; AAccess : TArgumentAccess) : TPasArgument;
  306. Function ParseType(ASource : String; CC : TCallingConvention; ATypeClass : TClass;Const AHint : String = '') : TPasProcedureType; virtual; overload;
  307. Procedure DoTestProcedureDecl(CC : TCallingConvention; Const AHint : String);
  308. Procedure DoTestProcedureOneArgDecl(CC : TCallingConvention; Const AHint : String);
  309. Procedure DoTestProcedureOneVarArgDecl(CC : TCallingConvention; Const AHint : String);
  310. Procedure DoTestProcedureOneConstArgDecl(CC : TCallingConvention; Const AHint : String);
  311. Procedure DoTestProcedureOneOutArgDecl(CC : TCallingConvention; Const AHint : String);
  312. Procedure DoTestProcedureTwoArgsDecl(CC : TCallingConvention; Const AHint : String);
  313. Procedure DoTestProcedureTwoVarArgsDecl(CC : TCallingConvention; Const AHint : String);
  314. Procedure DoTestProcedureTwoConstArgsDecl(CC : TCallingConvention; Const AHint : String);
  315. Procedure DoTestProcedureTwoOutArgsDecl(CC : TCallingConvention; Const AHint : String);
  316. Procedure DoTestProcedureTwoCombinedArgsDecl(CC : TCallingConvention; Const AHint : String);
  317. Procedure DoTestProcedureTwoCombinedVarArgsDecl(CC : TCallingConvention; Const AHint : String);
  318. Procedure DoTestProcedureTwoCombinedConstArgsDecl(CC : TCallingConvention; Const AHint : String);
  319. Procedure DoTestProcedureTwoCombinedOutArgsDecl(CC : TCallingConvention; Const AHint : String);
  320. Procedure DoTestProcedureDefaultConstArgsDecl(CC : TCallingConvention; Const AHint : String);
  321. procedure DoTestProcedureUntypedArgDecl(CC: TCallingConvention; const AHint: String);
  322. procedure DoTestProcedureUntypedConstArgDecl(CC: TCallingConvention; const AHint: String);
  323. procedure DoTestProcedureUntypedOutArgDecl(CC: TCallingConvention; const AHint: String);
  324. procedure DoTestProcedureUntypedDefArg;
  325. Procedure TestCallingConventions(Proc : TCallingConventionTest; Const AHint : String);
  326. Procedure TestCallingConventions(Proc : TCallingConventionTest);
  327. Function FuncProc : TPasFunctionType;
  328. Property Proc : TPasProcedureType Read FProc;
  329. Published
  330. Procedure TestProcedure;
  331. Procedure TestProcedureOneArg;
  332. Procedure TestProcedureOneVarArg;
  333. Procedure TestProcedureOneConstArg;
  334. Procedure TestProcedureOneOutArg;
  335. Procedure TestProcedureTwoArgs;
  336. Procedure TestProcedureTwoVarArgs;
  337. Procedure TestProcedureTwoConstArgs;
  338. Procedure TestProcedureTwoOutArgs;
  339. Procedure TestProcedureTwoCombinedArgs;
  340. Procedure TestProcedureTwoCombinedVarArgs;
  341. Procedure TestProcedureTwoCombinedConstArgs;
  342. Procedure TestProcedureTwoCombinedOutArgs;
  343. Procedure TestProcedureDefaultConstArgs;
  344. Procedure TestProcedureUntypedArg;
  345. Procedure TestProcedureUntypedConstArg;
  346. Procedure TestProcedureUntypedOutArg;
  347. Procedure TestProcedureUntypedDefArg;
  348. Procedure TestProcedureOneArgDefault;
  349. Procedure TestProcedureOneArgDefaultExpr;
  350. Procedure TestProcedureOneArgDefaultSet;
  351. Procedure TestProcedureOneVarArgDefault;
  352. Procedure TestProcedureOneConstArgDefault;
  353. Procedure TestProcedureOneOutArgDefault;
  354. Procedure TestProcedureNoMultiArgDefaults;
  355. Procedure TestProcedureOpenArray;
  356. Procedure TestProcedureConstOpenArray;
  357. Procedure TestProcedureOutOpenArray;
  358. Procedure TestProcedureVarOpenArray;
  359. Procedure TestProcedureArrayOfConst;
  360. Procedure TestProcedureOfObject;
  361. Procedure TestProcedureOfObjectOneArg;
  362. Procedure TestProcedureIsNested;
  363. Procedure TestProcedureIsNesteOneArg;
  364. Procedure TestFunction;
  365. Procedure TestFunctionOneArg;
  366. Procedure TestFunctionOfObject;
  367. Procedure TestFunctionOneArgOfObject;
  368. end;
  369. implementation
  370. uses typinfo;
  371. { TTestProcedureTypeParser }
  372. procedure TTestProcedureTypeParser.DoTestProcedureUntypedArgDecl(
  373. CC: TCallingConvention; const AHint: String);
  374. Var
  375. A : TPasArgument;
  376. begin
  377. ParseType('procedure(var A)',CC,TPasProcedureType,AHint);
  378. AssertEquals('Argument count',1,Proc.Args.Count);
  379. A:=CheckArgument(0,'A','',argVar);
  380. AssertNull('No argument type', A.ArgType)
  381. end;
  382. procedure TTestProcedureTypeParser.DoTestProcedureUntypedConstArgDecl(
  383. CC: TCallingConvention; const AHint: String);
  384. Var
  385. A : TPasArgument;
  386. begin
  387. ParseType('procedure(const A)',CC,TPasProcedureType,AHint);
  388. AssertEquals('Argument count',1,Proc.Args.Count);
  389. A:=CheckArgument(0,'A','',argConst);
  390. AssertNull('No argument type', A.ArgType)
  391. end;
  392. procedure TTestProcedureTypeParser.DoTestProcedureUntypedOutArgDecl(
  393. CC: TCallingConvention; const AHint: String);
  394. Var
  395. A : TPasArgument;
  396. begin
  397. ParseType('procedure(out A)',CC,TPasProcedureType,AHint);
  398. AssertEquals('Argument count',1,Proc.Args.Count);
  399. A:=CheckArgument(0,'A','',argOut);
  400. AssertNull('No argument type', A.ArgType)
  401. end;
  402. procedure TTestProcedureTypeParser.DoTestProcedureUntypedDefArg;
  403. begin
  404. ParseType('procedure(A)',ccdefault,TPasProcedureType,'');
  405. end;
  406. procedure TTestProcedureTypeParser.DoTestProcedureOneVarArgDefault(
  407. CC: TCallingConvention; const AHint: String);
  408. Var
  409. A : TPasArgument;
  410. begin
  411. ParseType('procedure(var A : Integer = 1)',CC,TPasProcedureType,AHint);
  412. AssertEquals('Argument count',1,Proc.Args.Count);
  413. A:=CheckArgument(0,'A','Integer',argVar);
  414. AssertNotNull('have default argument type', A.Value);
  415. AssertEquals('argument expr type', TPrimitiveExpr, A.ValueExpr.ClassType);
  416. AssertEquals('argument expr type', '1', TPrimitiveExpr(A.ValueExpr).Value);
  417. end;
  418. procedure TTestProcedureTypeParser.DoTestProcedureOneOutArgDefault(
  419. CC: TCallingConvention; const AHint: String);
  420. Var
  421. A : TPasArgument;
  422. begin
  423. ParseType('procedure(out A : Integer = 1)',CC,TPasProcedureType,AHint);
  424. AssertEquals('Argument count',1,Proc.Args.Count);
  425. A:=CheckArgument(0,'A','Integer',argOut);
  426. AssertNotNull('have default argument type', A.Value);
  427. AssertEquals('argument expr type', TPrimitiveExpr, A.ValueExpr.ClassType);
  428. AssertEquals('argument expr type', '1', TPrimitiveExpr(A.ValueExpr).Value);
  429. end;
  430. procedure TTestProcedureTypeParser.DoTestProcedureOneConstArgDefault(
  431. CC: TCallingConvention; const AHint: String);
  432. Var
  433. A : TPasArgument;
  434. begin
  435. ParseType('procedure(const A : Integer = 1)',CC,TPasProcedureType,AHint);
  436. AssertEquals('Argument count',1,Proc.Args.Count);
  437. A:=CheckArgument(0,'A','Integer',argConst);
  438. AssertNotNull('have default argument type', A.Value);
  439. AssertEquals('argument expr type', TPrimitiveExpr, A.ValueExpr.ClassType);
  440. AssertEquals('argument expr type', '1', TPrimitiveExpr(A.ValueExpr).Value);
  441. end;
  442. procedure TTestProcedureTypeParser.DoTestProcedureArrayOfConst(
  443. CC: TCallingConvention; const AHint: String);
  444. begin
  445. ParseType('procedure(A : Array of const)',CC,TPasProcedureType,AHint);
  446. AssertEquals('Argument count',1,Proc.Args.Count);
  447. CheckArrayOfConstArgument(0,argDefault);
  448. end;
  449. procedure TTestProcedureTypeParser.DoTestProcedureOfObject(
  450. CC: TCallingConvention; const AHint: String);
  451. begin
  452. ParseType('procedure of Object',CC,TPasProcedureType,AHint);
  453. AssertEquals('Argument count',0,Proc.Args.Count);
  454. AssertEquals('Is OF Object',True,Proc.IsOfObject);
  455. end;
  456. procedure TTestProcedureTypeParser.DoTestProcedureOfObjectOneArg(
  457. CC: TCallingConvention; const AHint: String);
  458. begin
  459. ParseType('procedure (A : integer)of Object',CC,TPasProcedureType,AHint);
  460. AssertEquals('Argument count',1,Proc.Args.Count);
  461. AssertEquals('Is OF Object',True,Proc.IsOfObject);
  462. CheckArgument(0,'A','Integer',argDefault);
  463. end;
  464. procedure TTestProcedureTypeParser.DoTestProcedureIsNested(
  465. CC: TCallingConvention; const AHint: String);
  466. begin
  467. ParseType('procedure is nested',CC,TPasProcedureType,AHint);
  468. AssertEquals('Argument count',0,Proc.Args.Count);
  469. AssertEquals('Is nested',True,Proc.IsNested);
  470. end;
  471. procedure TTestProcedureTypeParser.DoTestProcedureIsNestedOneArg(
  472. CC: TCallingConvention; const AHint: String);
  473. begin
  474. ParseType('procedure (A : integer) is nested',CC,TPasProcedureType,AHint);
  475. AssertEquals('Argument count',1,Proc.Args.Count);
  476. AssertEquals('Is nested',True,Proc.IsNested);
  477. CheckArgument(0,'A','Integer',argDefault);
  478. end;
  479. procedure TTestProcedureTypeParser.CheckArrayOfConstArgument(Aindex : Integer; Ac : TArgumentAccess);
  480. Var
  481. A : TPasArgument;
  482. T : TPasArrayType;
  483. begin
  484. A:=CheckArgument(Aindex,'A','',ac);
  485. AssertEquals('ArrayType',TPasArrayType,A.ArgType.ClassType);
  486. T:=A.ArgType as TPasArrayType;
  487. AssertNull('Have Element type',T.ElType);
  488. end;
  489. procedure TTestProcedureTypeParser.DoTestFunction(CC: TCallingConvention;
  490. const AHint: String);
  491. begin
  492. ParseType('function : integer',CC,TPasFunctionType,AHint);
  493. AssertEquals('Argument count',0,Proc.Args.Count);
  494. AssertEquals('Is OF Object',False,Proc.IsOfObject);
  495. AssertNotNull('Have result',FuncProc.ResultEl);
  496. AssertEquals('Result type class',TPasResultElement,FuncProc.ResultEl.ClassType);
  497. AssertNotNull('Have result',FuncProc.ResultEl.ResultType);
  498. AssertEquals('Result type element class ',TPasUnresolvedTypeRef,FuncProc.ResultEl.ResultType.ClassType);
  499. AssertEquals('Result type element name','Integer',FuncProc.ResultEl.ResultType.Name);
  500. end;
  501. procedure TTestProcedureTypeParser.DoTestFunctionOfObject(CC: TCallingConvention;
  502. const AHint: String);
  503. begin
  504. ParseType('function : integer of object',CC,TPasFunctionType,AHint);
  505. AssertEquals('Argument count',0,Proc.Args.Count);
  506. AssertEquals('Is OF Object',True,Proc.IsOfObject);
  507. AssertNotNull('Have result',FuncProc.ResultEl);
  508. AssertEquals('Result type class',TPasResultElement,FuncProc.ResultEl.ClassType);
  509. AssertNotNull('Have result',FuncProc.ResultEl.ResultType);
  510. AssertEquals('Result type element class ',TPasUnresolvedTypeRef,FuncProc.ResultEl.ResultType.ClassType);
  511. AssertEquals('Result type element name','Integer',FuncProc.ResultEl.ResultType.Name);
  512. end;
  513. procedure TTestProcedureTypeParser.DoTestFunctionOneArg(CC: TCallingConvention;
  514. const AHint: String);
  515. begin
  516. ParseType('function (A : Integer) : Integer',CC,TPasFunctionType,AHint);
  517. AssertEquals('Argument count',1,Proc.Args.Count);
  518. CheckArgument(0,'A','Integer',argDefault);
  519. AssertNotNull('Have result',FuncProc.ResultEl);
  520. AssertEquals('Result type class',TPasResultElement,FuncProc.ResultEl.ClassType);
  521. AssertNotNull('Have result',FuncProc.ResultEl.ResultType);
  522. AssertEquals('Result type element class ',TPasUnresolvedTypeRef,FuncProc.ResultEl.ResultType.ClassType);
  523. AssertEquals('Result type element name','Integer',FuncProc.ResultEl.ResultType.Name);
  524. end;
  525. procedure TTestProcedureTypeParser.DoTestFunctionOneArgOfObject(
  526. CC: TCallingConvention; const AHint: String);
  527. begin
  528. ParseType('function (A : Integer) : Integer of object',CC,TPasFunctionType,AHint);
  529. AssertEquals('Argument count',1,Proc.Args.Count);
  530. AssertEquals('Is OF Object',True,Proc.IsOfObject);
  531. CheckArgument(0,'A','Integer',argDefault);
  532. AssertNotNull('Have result',FuncProc.ResultEl);
  533. AssertEquals('Result type class',TPasResultElement,FuncProc.ResultEl.ClassType);
  534. AssertNotNull('Have result',FuncProc.ResultEl.ResultType);
  535. AssertEquals('Result type element class ',TPasUnresolvedTypeRef,FuncProc.ResultEl.ResultType.ClassType);
  536. AssertEquals('Result type element name','Integer',FuncProc.ResultEl.ResultType.Name);
  537. end;
  538. procedure TTestProcedureTypeParser.CheckOpenArrayArgument(Ac : TArgumentAccess);
  539. Var
  540. A : TPasArgument;
  541. T : TPasArrayType;
  542. begin
  543. A:=CheckArgument(0,'A','',ac);
  544. AssertEquals('ArrayType',TPasArrayType,A.ArgType.ClassType);
  545. T:=A.ArgType as TPasArrayType;
  546. AssertNotNull('Have Element type',T.ElType);
  547. AssertEquals('Element type',TPasUnresolvedTypeRef,T.ElType.ClassType);
  548. AssertEquals('Element type name','Integer',TPasUnresolvedTypeRef(T.ElType).Name);
  549. AssertEquals('No boundaries','',T.IndexRange);
  550. end;
  551. procedure TTestProcedureTypeParser.DoTestProcedureOpenArray(
  552. CC: TCallingConvention; const AHint: String);
  553. begin
  554. ParseType('procedure(A : Array of integer)',CC,TPasProcedureType,AHint);
  555. AssertEquals('Argument count',1,Proc.Args.Count);
  556. CheckOpenArrayArgument(argDefault);
  557. end;
  558. procedure TTestProcedureTypeParser.DoTestProcedureConstOpenArray(
  559. CC: TCallingConvention; const AHint: String);
  560. begin
  561. ParseType('procedure(const A : Array of integer)',CC,TPasProcedureType,AHint);
  562. AssertEquals('Argument count',1,Proc.Args.Count);
  563. CheckOpenArrayArgument(argConst);
  564. end;
  565. procedure TTestProcedureTypeParser.DoTestProcedureVarOpenArray(
  566. CC: TCallingConvention; const AHint: String);
  567. begin
  568. ParseType('procedure(var A : Array of integer)',CC,TPasProcedureType,AHint);
  569. AssertEquals('Argument count',1,Proc.Args.Count);
  570. CheckOpenArrayArgument(argVar);
  571. end;
  572. procedure TTestProcedureTypeParser.DoTestProcedureOutOpenArray(
  573. CC: TCallingConvention; const AHint: String);
  574. begin
  575. ParseType('procedure(out A : Array of integer)',CC,TPasProcedureType,AHint);
  576. AssertEquals('Argument count',1,Proc.Args.Count);
  577. CheckOpenArrayArgument(argOut);
  578. end;
  579. procedure TTestProcedureTypeParser.DoTestProcedureOneArgDefault(
  580. CC: TCallingConvention; const AHint: String);
  581. Var
  582. A : TPasArgument;
  583. begin
  584. ParseType('procedure(A : Integer = 1)',CC,TPasProcedureType,AHint);
  585. AssertEquals('Argument count',1,Proc.Args.Count);
  586. A:=CheckArgument(0,'A','Integer',argDefault);
  587. AssertNotNull('have default argument type', A.ValueExpr);
  588. AssertEquals('argument expr type', TPrimitiveExpr, A.ValueExpr.ClassType);
  589. AssertEquals('argument expr value', '1', TPrimitiveExpr(A.ValueExpr).Value);
  590. end;
  591. procedure TTestProcedureTypeParser.DoTestProcedureOneArgDefaultExpr(
  592. CC: TCallingConvention; const AHint: String);
  593. Var
  594. A : TPasArgument;
  595. B : TBinaryExpr;
  596. begin
  597. ParseType('procedure(A : Integer = 1+2)',CC,TPasProcedureType,AHint);
  598. AssertEquals('Argument count',1,Proc.Args.Count);
  599. A:=CheckArgument(0,'A','Integer',argDefault);
  600. AssertNotNull('have default argument type', A.ValueExpr);
  601. AssertEquals('argument expr type', TBinaryExpr, A.ValueExpr.ClassType);
  602. B:=TBinaryExpr(A.ValueExpr);
  603. AssertNotNull('have left expr', B.Left);
  604. AssertEquals('argument left expr type', TPrimitiveExpr, B.left.ClassType);
  605. AssertEquals('argument left expr value', '1', TPrimitiveExpr(B.Left).Value);
  606. AssertNotNull('have right expr', B.Right);
  607. AssertEquals('argument right expr type', TPrimitiveExpr, B.right.ClassType);
  608. AssertEquals('argument right expr value', '2', TPrimitiveExpr(B.right).Value);
  609. end;
  610. procedure TTestProcedureTypeParser.DoTestProcedureOneArgDefaultSet(
  611. CC: TCallingConvention; const AHint: String);
  612. Var
  613. A : TPasArgument;
  614. B : TParamsExpr;
  615. begin
  616. ParseType('procedure(A : TB = [])',CC,TPasProcedureType,AHint);
  617. AssertEquals('Argument count',1,Proc.Args.Count);
  618. A:=CheckArgument(0,'A','TB',argDefault);
  619. AssertNotNull('have default argument type', A.ValueExpr);
  620. AssertEquals('argument expr type', TParamsExpr, A.ValueExpr.ClassType);
  621. B:=TParamsExpr(A.ValueExpr);
  622. AssertEquals('No params',0,Length(B.Params));
  623. end;
  624. Function TTestProcedureTypeParser.CheckArgument(AIndex: Integer; const AName,
  625. ATypeName: String; AAccess: TArgumentAccess) : TPAsArgument;
  626. Var
  627. A : TPasArgument;
  628. C : String;
  629. begin
  630. C:='Argument '+IntToStr(AIndex)+' : ';
  631. AssertNotNull(C+'assigned',Proc.Args[AIndex]);
  632. AssertEquals(C+'class',TPasArgument,TObject(Proc.Args[AIndex]).ClassType);
  633. A:=TPasArgument(Proc.Args[AIndex]);
  634. AssertEquals(C+'Access',AAccess,A.Access);
  635. AssertEquals(C+'name',AName,A.Name);
  636. if (ATypeName<>'') then
  637. begin
  638. AssertNotNull(C+'type assigned',A.ArgType);
  639. if (ATypeName[1]='[') then
  640. AssertEquals(C+'type classname',LowerCase(Copy(ATypeName,2,Length(ATypeName)-2)),LowerCase(A.ArgType.ClassName))
  641. else
  642. AssertEquals(C+'type name',ATypeName,A.ArgType.Name);
  643. end;
  644. Result:=A;
  645. end;
  646. function TTestProcedureTypeParser.ParseType(ASource: String;
  647. CC: TCallingConvention; ATypeClass: TClass; const AHint: String): TPasProcedureType;
  648. begin
  649. if CC=ccdefault then
  650. Result:=TPasProcedureType(ParseType(ASource,ATypeClass,AHint))
  651. else
  652. begin
  653. if (AHint<>'') then
  654. Result:=TPasProcedureType(ParseType(ASource+';' +cCallingConventions[CC]+';',ATypeClass,AHint))
  655. else
  656. Result:=TPasProcedureType(ParseType(ASource+';' +cCallingConventions[CC],ATypeClass,AHint));
  657. end;
  658. FProc:=Result;
  659. AssertEquals('Correct calling convention for procedural type',cc,Result.CallingConvention);
  660. end;
  661. procedure TTestProcedureTypeParser.DoTestProcedureDecl(CC: TCallingConvention; Const AHint : String);
  662. begin
  663. ParseType('procedure',CC,TPasProcedureType,AHint);
  664. AssertEquals('Argument count',0,Proc.Args.Count);
  665. end;
  666. procedure TTestProcedureTypeParser.DoTestProcedureOneArgDecl(
  667. CC: TCallingConvention; const AHint: String);
  668. begin
  669. ParseType('procedure(A : Integer)',CC,TPasProcedureType,AHint);
  670. AssertEquals('Argument count',1,Proc.Args.Count);
  671. CheckArgument(0,'A','Integer',argDefault);
  672. end;
  673. procedure TTestProcedureTypeParser.DoTestProcedureOneVarArgDecl(
  674. CC: TCallingConvention; const AHint: String);
  675. begin
  676. ParseType('procedure(var A : Integer)',CC,TPasProcedureType,AHint);
  677. AssertEquals('Argument count',1,Proc.Args.Count);
  678. CheckArgument(0,'A','Integer',argVar);
  679. end;
  680. procedure TTestProcedureTypeParser.DoTestProcedureOneConstArgDecl(
  681. CC: TCallingConvention; const AHint: String);
  682. begin
  683. ParseType('procedure(const A : Integer)',CC,TPasProcedureType,AHint);
  684. AssertEquals('Argument count',1,Proc.Args.Count);
  685. CheckArgument(0,'A','Integer',argConst);
  686. end;
  687. procedure TTestProcedureTypeParser.DoTestProcedureOneOutArgDecl(
  688. CC: TCallingConvention; const AHint: String);
  689. begin
  690. ParseType('procedure(out A : Integer)',CC,TPasProcedureType,AHint);
  691. AssertEquals('Argument count',1,Proc.Args.Count);
  692. CheckArgument(0,'A','Integer',argOut);
  693. end;
  694. procedure TTestProcedureTypeParser.DoTestProcedureTwoArgsDecl(
  695. CC: TCallingConvention; const AHint: String);
  696. begin
  697. ParseType('procedure(A : Integer;B : String)',CC,TPasProcedureType,AHint);
  698. AssertEquals('Argument count',2,Proc.Args.Count);
  699. CheckArgument(0,'A','Integer',argDefault);
  700. CheckArgument(1,'B','[TPasAliasType]',argDefault);
  701. end;
  702. procedure TTestProcedureTypeParser.DoTestProcedureTwoVarArgsDecl(
  703. CC: TCallingConvention; const AHint: String);
  704. begin
  705. ParseType('procedure(Var A : Integer;Var B : String)',CC,TPasProcedureType,AHint);
  706. AssertEquals('Argument count',2,Proc.Args.Count);
  707. CheckArgument(0,'A','Integer',argVar);
  708. CheckArgument(1,'B','[TPasAliasType]',argVar);
  709. end;
  710. procedure TTestProcedureTypeParser.DoTestProcedureTwoConstArgsDecl(
  711. CC: TCallingConvention; const AHint: String);
  712. begin
  713. ParseType('procedure(const A : Integer;Const B : String)',CC,TPasProcedureType,AHint);
  714. AssertEquals('Argument count',2,Proc.Args.Count);
  715. CheckArgument(0,'A','Integer',argConst);
  716. CheckArgument(1,'B','[TPasAliasType]',argConst);
  717. end;
  718. procedure TTestProcedureTypeParser.DoTestProcedureTwoOutArgsDecl(
  719. CC: TCallingConvention; const AHint: String);
  720. begin
  721. ParseType('procedure(out A : Integer;Out B : String)',CC,TPasProcedureType,AHint);
  722. AssertEquals('Argument count',2,Proc.Args.Count);
  723. CheckArgument(0,'A','Integer',argOut);
  724. CheckArgument(1,'B','[TPasAliasType]',argOut);
  725. end;
  726. procedure TTestProcedureTypeParser.DoTestProcedureTwoCombinedArgsDecl(
  727. CC: TCallingConvention; const AHint: String);
  728. begin
  729. ParseType('procedure(A,B : Integer)',CC,TPasProcedureType,AHint);
  730. AssertEquals('Argument count',2,Proc.Args.Count);
  731. CheckArgument(0,'A','Integer',argDefault);
  732. CheckArgument(1,'B','Integer',argDefault);
  733. end;
  734. procedure TTestProcedureTypeParser.DoTestProcedureTwoCombinedVarArgsDecl(
  735. CC: TCallingConvention; const AHint: String);
  736. begin
  737. ParseType('procedure(Var A,B : Integer)',CC,TPasProcedureType,AHint);
  738. AssertEquals('Argument count',2,Proc.Args.Count);
  739. CheckArgument(0,'A','Integer',argVar);
  740. CheckArgument(1,'B','Integer',argVar);
  741. end;
  742. procedure TTestProcedureTypeParser.DoTestProcedureTwoCombinedConstArgsDecl(
  743. CC: TCallingConvention; const AHint: String);
  744. begin
  745. ParseType('procedure(Const A,B : Integer)',CC,TPasProcedureType,AHint);
  746. AssertEquals('Argument count',2,Proc.Args.Count);
  747. CheckArgument(0,'A','Integer',argConst);
  748. CheckArgument(1,'B','Integer',argConst);
  749. end;
  750. procedure TTestProcedureTypeParser.DoTestProcedureTwoCombinedOutArgsDecl(
  751. CC: TCallingConvention; const AHint: String);
  752. begin
  753. ParseType('procedure(Out A,B : Integer)',CC,TPasProcedureType,AHint);
  754. AssertEquals('Argument count',2,Proc.Args.Count);
  755. CheckArgument(0,'A','Integer',argOut);
  756. CheckArgument(1,'B','Integer',argOut);
  757. end;
  758. procedure TTestProcedureTypeParser.DoTestProcedureDefaultConstArgsDecl(
  759. CC: TCallingConvention; const AHint: String);
  760. begin
  761. ParseType('procedure(A : Integer; Const B : Integer)',CC,TPasProcedureType,AHint);
  762. AssertEquals('Argument count',2,Proc.Args.Count);
  763. CheckArgument(0,'A','Integer',argDefault);
  764. CheckArgument(1,'B','Integer',argConst);
  765. end;
  766. procedure TTestProcedureTypeParser.TestCallingConventions(
  767. Proc: TCallingConventionTest; Const AHint : String);
  768. Var
  769. CC : TCallingConvention;
  770. begin
  771. For cc:=ccDefault to High(TCallingConvention) do
  772. begin
  773. if CC<>ccDefault then
  774. Setup;
  775. try
  776. Proc(cc,AHint);
  777. finally
  778. tearDown;
  779. end;
  780. end;
  781. end;
  782. procedure TTestProcedureTypeParser.TestCallingConventions(
  783. Proc: TCallingConventionTest);
  784. begin
  785. TestCallingConventions(Proc,'');
  786. Setup;
  787. TestCallingConventions(Proc,'deprecated');
  788. Setup;
  789. TestCallingConventions(Proc,'platform');
  790. end;
  791. function TTestProcedureTypeParser.FuncProc: TPasFunctionType;
  792. begin
  793. Result:=Proc as TPasFunctionType;
  794. end;
  795. procedure TTestProcedureTypeParser.TestProcedure;
  796. begin
  797. TestCallingConventions(@DoTestProcedureDecl);
  798. end;
  799. procedure TTestProcedureTypeParser.TestProcedureOneArg;
  800. begin
  801. TestCallingConventions(@DoTestProcedureOneArgDecl);
  802. end;
  803. procedure TTestProcedureTypeParser.TestProcedureOneVarArg;
  804. begin
  805. TestCallingConventions(@DoTestProcedureOneVarArgDecl);
  806. end;
  807. procedure TTestProcedureTypeParser.TestProcedureOneConstArg;
  808. begin
  809. TestCallingConventions(@DoTestProcedureOneConstArgDecl);
  810. end;
  811. procedure TTestProcedureTypeParser.TestProcedureOneOutArg;
  812. begin
  813. TestCallingConventions(@DoTestProcedureOneOutArgDecl);
  814. end;
  815. procedure TTestProcedureTypeParser.TestProcedureTwoArgs;
  816. begin
  817. TestCallingConventions(@DoTestProcedureTwoArgsDecl);
  818. end;
  819. procedure TTestProcedureTypeParser.TestProcedureTwoVarArgs;
  820. begin
  821. TestCallingConventions(@DoTestProcedureTwoVarArgsDecl);
  822. end;
  823. procedure TTestProcedureTypeParser.TestProcedureTwoConstArgs;
  824. begin
  825. TestCallingConventions(@DoTestProcedureTwoConstArgsDecl);
  826. end;
  827. procedure TTestProcedureTypeParser.TestProcedureTwoOutArgs;
  828. begin
  829. TestCallingConventions(@DoTestProcedureTwoOutArgsDecl);
  830. end;
  831. procedure TTestProcedureTypeParser.TestProcedureTwoCombinedArgs;
  832. begin
  833. TestCallingConventions(@DoTestProcedureTwoCombinedArgsDecl);
  834. end;
  835. procedure TTestProcedureTypeParser.TestProcedureTwoCombinedVarArgs;
  836. begin
  837. TestCallingConventions(@DoTestProcedureTwoCombinedVarArgsDecl);
  838. end;
  839. procedure TTestProcedureTypeParser.TestProcedureTwoCombinedConstArgs;
  840. begin
  841. TestCallingConventions(@DoTestProcedureTwoCombinedConstArgsDecl);
  842. end;
  843. procedure TTestProcedureTypeParser.TestProcedureTwoCombinedOutArgs;
  844. begin
  845. TestCallingConventions(@DoTestProcedureTwoCombinedOutArgsDecl);
  846. end;
  847. procedure TTestProcedureTypeParser.TestProcedureDefaultConstArgs;
  848. begin
  849. TestCallingConventions(@DoTestProcedureDefaultConstArgsDecl);
  850. end;
  851. procedure TTestProcedureTypeParser.TestProcedureUntypedArg;
  852. begin
  853. TestCallingConventions(@DoTestProcedureUntypedArgDecl);
  854. end;
  855. procedure TTestProcedureTypeParser.TestProcedureUntypedConstArg;
  856. begin
  857. TestCallingConventions(@DoTestProcedureUntypedConstArgDecl);
  858. end;
  859. procedure TTestProcedureTypeParser.TestProcedureUntypedOutArg;
  860. begin
  861. TestCallingConventions(@DoTestProcedureUntypedOutArgDecl);
  862. end;
  863. procedure TTestProcedureTypeParser.TestProcedureUntypedDefArg;
  864. begin
  865. AssertException('No untyped arg by value',EParserError,@DoTestProcedureUntypedDefArg)
  866. end;
  867. procedure TTestProcedureTypeParser.TestProcedureOneArgDefault;
  868. begin
  869. TestCallingConventions(@DoTestProcedureOneArgDefault);
  870. end;
  871. procedure TTestProcedureTypeParser.TestProcedureOneArgDefaultExpr;
  872. begin
  873. TestCallingConventions(@DoTestProcedureOneArgDefaultExpr);
  874. end;
  875. procedure TTestProcedureTypeParser.TestProcedureOneArgDefaultSet;
  876. begin
  877. TestCallingConventions(@DoTestProcedureOneArgDefaultSet);
  878. end;
  879. procedure TTestProcedureTypeParser.TestProcedureOneVarArgDefault;
  880. begin
  881. TestCallingConventions(@DoTestProcedureOneVarArgDefault);
  882. end;
  883. procedure TTestProcedureTypeParser.TestProcedureOneConstArgDefault;
  884. begin
  885. TestCallingConventions(@DoTestProcedureOneConstArgDefault);
  886. end;
  887. procedure TTestProcedureTypeParser.TestProcedureOneOutArgDefault;
  888. begin
  889. TestCallingConventions(@DoTestProcedureOneOutArgDefault);
  890. end;
  891. procedure TTestProcedureTypeParser.TestProcedureNoMultiArgDefaults;
  892. begin
  893. AssertParseTypeError('procedure (A,B : Integer = 1)');
  894. end;
  895. procedure TTestProcedureTypeParser.TestProcedureOpenArray;
  896. begin
  897. TestCallingConventions(@DoTestProcedureOpenArray);
  898. end;
  899. procedure TTestProcedureTypeParser.TestProcedureConstOpenArray;
  900. begin
  901. TestCallingConventions(@DoTestProcedureConstOpenArray);
  902. end;
  903. procedure TTestProcedureTypeParser.TestProcedureOutOpenArray;
  904. begin
  905. TestCallingConventions(@DoTestProcedureVarOpenArray);
  906. end;
  907. procedure TTestProcedureTypeParser.TestProcedureVarOpenArray;
  908. begin
  909. TestCallingConventions(@DoTestProcedureOutOpenArray);
  910. end;
  911. procedure TTestProcedureTypeParser.TestProcedureArrayOfConst;
  912. begin
  913. TestCallingConventions(@DoTestProcedureArrayOfConst);
  914. end;
  915. procedure TTestProcedureTypeParser.TestProcedureOfObject;
  916. begin
  917. TestCallingConventions(@DoTestProcedureOfObject);
  918. end;
  919. procedure TTestProcedureTypeParser.TestProcedureOfObjectOneArg;
  920. begin
  921. TestCallingConventions(@DoTestProcedureOfObjectOneArg);
  922. end;
  923. procedure TTestProcedureTypeParser.TestProcedureIsNested;
  924. begin
  925. TestCallingConventions(@DoTestProcedureIsNested);
  926. end;
  927. procedure TTestProcedureTypeParser.TestProcedureIsNesteOneArg;
  928. begin
  929. TestCallingConventions(@DoTestProcedureIsNestedOneArg);
  930. end;
  931. procedure TTestProcedureTypeParser.TestFunction;
  932. begin
  933. TestCallingConventions(@DoTestFunction);
  934. end;
  935. procedure TTestProcedureTypeParser.TestFunctionOneArg;
  936. begin
  937. TestCallingConventions(@DoTestFunctionOneArg);
  938. end;
  939. procedure TTestProcedureTypeParser.TestFunctionOfObject;
  940. begin
  941. TestCallingConventions(@DoTestFunctionOfObject);
  942. end;
  943. procedure TTestProcedureTypeParser.TestFunctionOneArgOfObject;
  944. begin
  945. TestCallingConventions(@DoTestFunctionOneArgOfObject);
  946. end;
  947. { TTestRecordTypeParser }
  948. function TTestRecordTypeParser.GetField(AIndex: Integer; R: TPasRecordType
  949. ): TPasVariable;
  950. begin
  951. AssertNotNull(R);
  952. AssertNotNull(R.Members);
  953. AssertTrue('Have AIndex elements',R.Members.Count>AIndex);
  954. AssertEquals('Correct class in member',TPasVariable,TObject(R.Members[AIndex]).ClassType);
  955. Result:=TPasVariable(R.Members[AIndex]);
  956. end;
  957. function TTestRecordTypeParser.GetField(AIndex: Integer; R: TPasVariant
  958. ): TPasVariable;
  959. begin
  960. AssertNotNull(R);
  961. AssertNotNull('Have variant members', R.Members);
  962. AssertNotNull('Have variant members member list',R.Members.Members);
  963. AssertTrue('Have AIndex elements',R.Members.Members.Count>AIndex);
  964. AssertEquals('Correct class in member',TPasVariable,TObject(R.Members.members[AIndex]).ClassType);
  965. Result:=TPasVariable(R.Members.Members[AIndex]);
  966. end;
  967. function TTestRecordTypeParser.GetF(AIndex: Integer): TPasVariable;
  968. begin
  969. Result:=GetField(AIndex,GetR);
  970. end;
  971. function TTestRecordTypeParser.GetR: TPasRecordType;
  972. begin
  973. Result:=TheType as TPasRecordType;
  974. end;
  975. function TTestRecordTypeParser.GetVariant(AIndex: Integer; R: TPasRecordType
  976. ): TPasVariant;
  977. begin
  978. AssertNotNull(R);
  979. AssertNotNull(R.Variants);
  980. AssertTrue('Have AIndex variant elements',R.Variants.Count>AIndex);
  981. AssertEquals('Correct class in variant',TPasVariant,TObject(R.Variants[AIndex]).ClassType);
  982. Result:=TPasVariant(R.Variants[AIndex]);
  983. end;
  984. function TTestRecordTypeParser.GetV(AIndex: Integer): TPasVariant;
  985. begin
  986. Result:=GetVariant(AIndex,GetR);
  987. end;
  988. procedure TTestRecordTypeParser.TestFields(const Fields: array of string;
  989. AHint: String; HaveVariant: Boolean);
  990. Var
  991. S : String;
  992. I : integer;
  993. begin
  994. S:='';
  995. For I:=Low(Fields) to High(Fields) do
  996. begin
  997. if (S<>'') then
  998. S:=S+sLineBreak;
  999. S:=S+' '+Fields[i];
  1000. end;
  1001. if (S<>'') then
  1002. S:=S+sLineBreak;
  1003. S:='record'+sLineBreak+s+' end';
  1004. ParseType(S,TPasRecordType,AHint);
  1005. if HaveVariant then
  1006. begin
  1007. AssertNotNull('Have variants',TheRecord.Variants);
  1008. AssertNotNull('Have variant type',TheRecord.VariantType);
  1009. end
  1010. else
  1011. begin
  1012. AssertNull('No variants',TheRecord.Variants);
  1013. AssertNull('No variant type',TheRecord.VariantType);
  1014. AssertEquals('No variant name','',TheRecord.VariantName);
  1015. end;
  1016. end;
  1017. procedure TTestRecordTypeParser.AssertVariantSelector(AName,AType : string);
  1018. begin
  1019. if (AType='') then
  1020. AType:='Integer';
  1021. AssertEquals('Have variant selector storage name',AName,TheRecord.VariantName);
  1022. AssertNotNull('Have variant selector type',TheRecord.VariantType);
  1023. AssertEquals('Have variant selector type',TPasUnresolvedTypeRef,TheRecord.VariantType.ClassType);
  1024. AssertEquals('Have variant selector type name',AType,TheRecord.VariantType.Name);
  1025. end;
  1026. procedure TTestRecordTypeParser.DoTestEmpty(const AHint: String);
  1027. begin
  1028. TestFields([],AHint);
  1029. AssertNotNull('Have members array',TheRecord.Members);
  1030. AssertEquals('Zero members in array',0,TheRecord.Members.Count);
  1031. end;
  1032. procedure TTestRecordTypeParser.AssertVariant1(Hints: TPasMemberHints);
  1033. begin
  1034. AssertVariant1(Hints,['0']);
  1035. end;
  1036. procedure TTestRecordTypeParser.AssertVariant1(Hints: TPasMemberHints; VariantLabels : Array of string);
  1037. Var
  1038. I : Integer;
  1039. begin
  1040. AssertNotNull('Have variant 1',Variant1);
  1041. AssertNotNull('Variant 1 has Values ',Variant1.Values);
  1042. if Length(VariantLabels)=0 then
  1043. begin
  1044. AssertEquals('Have 1 value',1,Variant1.Values.Count);
  1045. AssertNotNull('Assigned value',Variant1.Values[0]);
  1046. AssertEquals('Expression',TPrimitiveExpr,TObject(Variant1.Values[0]).CLassType);
  1047. AssertExpression('First value is 0',TPasExpr(Variant1.Values[0]),pekNumber,'0');
  1048. end
  1049. else
  1050. begin
  1051. AssertEquals('Have correct number of values',Length(VariantLabels),Variant1.Values.Count);
  1052. For I:=0 to Length(VariantLabels)-1 do
  1053. begin
  1054. AssertEquals(Format('Expression for variant %d',[I]),TPrimitiveExpr,TObject(Variant1.Values[0]).CLassType);
  1055. AssertExpression(Format('Value %d is %s',[i,VariantLabels[i]]),TPasExpr(Variant1.Values[I]),pekNumber,VariantLabels[i]);
  1056. end;
  1057. end;
  1058. AssertNotNull('Have members',Variant1.Members);
  1059. AssertNotNull('Have member members',Variant1.Members.Members);
  1060. AssertNotNull('member 0 not null',Variant1.Members.Members[0]);
  1061. AssertEquals('Member 0 has correct name',TPasVariable,TObject(Variant1.Members.Members[0]).ClassType);
  1062. AssertEquals('Member 0 has correct name','y',TPasVariable(Variant1.Members.Members[0]).Name);
  1063. AssertNotNull('member 0 has not null type',TPasVariable(Variant1.Members.Members[0]).VarType);
  1064. AssertEquals('member 0 has correct type',TPasUnresolvedTypeRef,TPasVariable(Variant1.Members.Members[0]).VarType.ClassType);
  1065. AssertEquals('member 0 has correct type name','Integer',TPasVariable(Variant1.Members.Members[0]).VarType.Name);
  1066. AssertTrue('Field 1 hints match',TPasVariable(Variant1.Members.Members[0]).Hints=Hints)
  1067. end;
  1068. procedure TTestRecordTypeParser.AssertVariant2(Hints: TPasMemberHints);
  1069. begin
  1070. AssertVariant2(Hints,['1']);
  1071. end;
  1072. procedure TTestRecordTypeParser.AssertVariant2(Hints: TPasMemberHints; VariantLabels : Array of string);
  1073. Var
  1074. I : Integer;
  1075. begin
  1076. AssertNotNull('Have variant 2',Variant2);
  1077. AssertNotNull('Variant 2 has Values ',Variant2.Values);
  1078. if Length(VariantLabels)=0 then
  1079. begin
  1080. AssertEquals('Variant 2 has 1 value',2,Variant2.Values.Count);
  1081. AssertEquals('Expression',TPrimitiveExpr,TObject(Variant2.Values[0]).CLassType);
  1082. AssertExpression('First value is 1',TPasExpr(Variant2.Values[0]),pekNumber,'1');
  1083. end
  1084. else
  1085. begin
  1086. AssertEquals('Variant 2 Has correct number of values',Length(VariantLabels),Variant2.Values.Count);
  1087. For I:=0 to Length(VariantLabels)-1 do
  1088. begin
  1089. AssertEquals(Format('Expression for variant %d',[I]),TPrimitiveExpr,TObject(Variant2.Values[I]).CLassType);
  1090. AssertExpression(Format('Value %d is %s',[i,VariantLabels[i]]),TPasExpr(Variant2.Values[I]),pekNumber,VariantLabels[i]);
  1091. // AssertEquals(Format('Variant 2, Value %d is %s',[i,VariantLabels[i]]),VariantLabels[i],Variant2.Values[I]);
  1092. end;
  1093. end;
  1094. AssertNotNull('Have members',Variant2.Members);
  1095. AssertNotNull('Have member members',Variant2.Members.Members);
  1096. AssertNotNull('member 1 not null',Variant2.Members.Members[0]);
  1097. AssertEquals('Member 1 has correct name',TPasVariable,TObject(Variant2.Members.Members[0]).ClassType);
  1098. AssertEquals('Member 1 has correct name','z',TPasVariable(Variant2.Members.Members[0]).Name);
  1099. AssertNotNull('member 1 has not null type',TPasVariable(Variant2.Members.Members[0]).VarType);
  1100. AssertEquals('member 1 has correct type',TPasUnresolvedTypeRef,TPasVariable(Variant2.Members.Members[0]).VarType.ClassType);
  1101. AssertEquals('member 1 has correct type name','Integer',TPasVariable(Variant2.Members.Members[0]).VarType.Name);
  1102. AssertTrue('Field 1 hints match',TPasVariable(Variant2.Members.Members[0]).Hints=Hints)
  1103. end;
  1104. procedure TTestRecordTypeParser.DoTestVariantNoStorage(const AHint: string);
  1105. begin
  1106. TestFields(['x : integer;','case integer of','0 : (y : integer;)'],AHint,True);
  1107. AssertField1([]);
  1108. AssertVariantSelector('','');
  1109. AssertVariant1([]);
  1110. end;
  1111. procedure TTestRecordTypeParser.DoTestDeprecatedVariantNoStorage(
  1112. const AHint: string);
  1113. begin
  1114. TestFields(['x : integer;','case integer of','0 : (y : integer deprecated;)'],AHint,True);
  1115. AssertField1([]);
  1116. AssertVariantSelector('','');
  1117. AssertVariant1([hDeprecated]);
  1118. end;
  1119. procedure TTestRecordTypeParser.DoTestDeprecatedVariantStorage(
  1120. const AHint: string);
  1121. begin
  1122. TestFields(['x : integer;','case s : integer of','0 : (y : integer deprecated;)'],AHint,True);
  1123. AssertField1([]);
  1124. AssertVariantSelector('s','');
  1125. AssertVariant1([hDeprecated]);
  1126. end;
  1127. procedure TTestRecordTypeParser.DoTestVariantStorage(const AHint: string);
  1128. begin
  1129. TestFields(['x : integer;','case s : integer of','0 : (y : integer;)'],AHint,True);
  1130. AssertField1([]);
  1131. AssertVariantSelector('s','');
  1132. AssertVariant1([]);
  1133. end;
  1134. procedure TTestRecordTypeParser.DoTestTwoVariantsNoStorage(const AHint: string
  1135. );
  1136. begin
  1137. TestFields(['x : integer;','case integer of','0 : (y : integer;);','1 : (z : integer;)'],AHint,True);
  1138. AssertField1([]);
  1139. AssertVariantSelector('','');
  1140. AssertVariant1([]);
  1141. AssertVariant2([]);
  1142. end;
  1143. procedure TTestRecordTypeParser.DoTestTwoVariantsStorage(const AHint: string);
  1144. begin
  1145. TestFields(['x : integer;','case s : integer of','0 : (y : integer;);','1 : (z : integer;)'],AHint,True);
  1146. AssertField1([]);
  1147. AssertVariantSelector('s','');
  1148. AssertVariant1([]);
  1149. Ass