123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- unit tcresolvegenerics;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, testregistry, tcresolver, PasResolveEval, PParser;
- type
- { TTestResolveGenerics }
- TTestResolveGenerics = Class(TCustomTestResolver)
- Published
- // generic functions
- procedure TestGen_GenericFunction; // ToDo
- // generic types
- procedure TestGen_MissingTemplateFail;
- procedure TestGen_VarTypeWithoutSpecializeFail;
- procedure TestGen_ConstraintStringFail;
- procedure TestGen_ConstraintMultiClassFail;
- procedure TestGen_ConstraintRecordExpectedFail;
- // ToDo: constraints mismatch: TAnt<T:record>; TBird<T:Class> = record v: TAnt<T> end Fail
- // ToDo: constraint keyword record
- // ToDo: constraint keyword class, constructor, class+constructor
- // ToDo: constraint T:Unit2.TBird
- // ToDo: constraint T:Unit2.TGen<word>
- procedure TestGen_GenericNotFoundFail;
- procedure TestGen_RecordLocalNameDuplicateFail;
- procedure TestGen_Record; // ToDo
- // ToDo: type TBird<T> = record end; var b: TBird<word>.T; fail
- // ToDo: enums within generic
- // ToDo: generic class
- // ToDo: generic class forward
- // ToDo: ancestor cycle: TBird<T> = class(TBird<word>) fail
- // ToDo: class-of
- // ToDo: UnitA.impl uses UnitB.intf uses UnitA.intf, UnitB has specialize of UnitA
- // ToDo: generic interface
- // ToDo: generic array
- // ToDo: generic procedure type
- // ToDo: pointer of generic
- // ToDo: generic helpers
- end;
- implementation
- { TTestResolveGenerics }
- procedure TTestResolveGenerics.TestGen_GenericFunction;
- begin
- StartProgram(false);
- Add([
- 'generic function DoIt<T>(a: T): T;',
- 'var i: T;',
- 'begin',
- ' a:=i;',
- ' Result:=a;',
- 'end;',
- 'var w: word;',
- 'begin',
- //' w:=DoIt<word>(3);',
- '']);
- ParseProgram;
- end;
- procedure TTestResolveGenerics.TestGen_MissingTemplateFail;
- begin
- StartProgram(false);
- Add([
- 'type generic g< > = array of word;',
- 'begin',
- '']);
- CheckParserException('Expected "Identifier"',nParserExpectTokenError);
- end;
- procedure TTestResolveGenerics.TestGen_VarTypeWithoutSpecializeFail;
- begin
- StartProgram(false);
- Add([
- 'type generic TBird<T> = record end;',
- 'var b: TBird;',
- 'begin',
- '']);
- CheckResolverException('Generics without specialization cannot be used as a type for a variable',
- nGenericsWithoutSpecializationAsType);
- end;
- procedure TTestResolveGenerics.TestGen_ConstraintStringFail;
- begin
- StartProgram(false);
- Add([
- 'generic function DoIt<T:string>(a: T): T;',
- 'begin',
- ' Result:=a;',
- 'end;',
- 'begin',
- '']);
- CheckResolverException('''string'' is not a valid constraint',
- nXIsNotAValidConstraint);
- end;
- procedure TTestResolveGenerics.TestGen_ConstraintMultiClassFail;
- begin
- StartProgram(false);
- Add([
- '{$mode objfpc}',
- 'type',
- ' TObject = class end;',
- ' TBird = class end;',
- ' TBear = class end;',
- 'generic function DoIt<T: TBird, TBear>(a: T): T;',
- 'begin',
- ' Result:=a;',
- 'end;',
- 'begin',
- '']);
- CheckResolverException('''TBird'' constraint and ''TBear'' constraint cannot be specified together',
- nConstraintXAndConstraintYCannotBeTogether);
- end;
- procedure TTestResolveGenerics.TestGen_ConstraintRecordExpectedFail;
- begin
- StartProgram(false);
- Add([
- '{$mode objfpc}',
- 'type',
- ' generic TBird<T:record> = record v: T; end;',
- 'var r: specialize TBird<word>;',
- 'begin',
- '']);
- CheckResolverException('record type expected, but Word found',
- nXExpectedButYFound);
- end;
- procedure TTestResolveGenerics.TestGen_GenericNotFoundFail;
- begin
- StartProgram(false);
- Add([
- '{$mode objfpc}',
- 'type',
- ' TBird = specialize TAnimal<word>;',
- 'begin',
- '']);
- CheckResolverException('identifier not found "TAnimal"',
- nIdentifierNotFound);
- end;
- procedure TTestResolveGenerics.TestGen_RecordLocalNameDuplicateFail;
- begin
- StartProgram(false);
- Add([
- '{$mode objfpc}',
- 'type',
- ' generic TBird<T> = record T: word; end;',
- 'begin',
- '']);
- CheckResolverException('Duplicate identifier "T" at afile.pp(4,18)',
- nDuplicateIdentifier);
- end;
- procedure TTestResolveGenerics.TestGen_Record;
- begin
- StartProgram(false);
- Add([
- '{$mode objfpc}',
- 'type',
- ' {#Typ}T = word;',
- ' generic TRec<{#Templ}T> = record',
- ' {=Templ}v: T;',
- ' end;',
- 'var',
- ' r: specialize TRec<word>;',
- ' {=Typ}w: T;',
- 'begin',
- ' r.v:=w;',
- '']);
- ParseProgram;
- end;
- initialization
- RegisterTests([TTestResolveGenerics]);
- end.
|