mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-12 13:49:51 +02:00
fcl-passrc: parser: position of generic function is in front of type params
git-svn-id: trunk@43056 -
This commit is contained in:
parent
bd1d6f335d
commit
2b76f439fe
@ -5097,7 +5097,7 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
writeln('TPasResolver.OnFindProc START ',El.Name,':',GetElementTypeName(El),' itself=',El=Data^.Proc);
|
//writeln('TPasResolver.OnFindProc START ',El.Name,':',GetElementTypeName(El),' itself=',El=Data^.Proc);
|
||||||
if not (El is TPasProcedure) then
|
if not (El is TPasProcedure) then
|
||||||
begin
|
begin
|
||||||
// identifier is not a proc
|
// identifier is not a proc
|
||||||
@ -8974,7 +8974,6 @@ begin
|
|||||||
DeclTemplates:=GetProcTemplateTypes(DeclProc);
|
DeclTemplates:=GetProcTemplateTypes(DeclProc);
|
||||||
if ImplTemplates<>nil then
|
if ImplTemplates<>nil then
|
||||||
begin
|
begin
|
||||||
writeln('AAA1 TPasResolver.ReplaceProcScopeImplArgsWithDeclArgs DeclProc=',DeclProc.Name,' ImplProc=',ImplProc.Name,' ',ImplTemplates.Count);
|
|
||||||
if (DeclTemplates=nil) or (ImplTemplates.Count<>DeclTemplates.Count) then
|
if (DeclTemplates=nil) or (ImplTemplates.Count<>DeclTemplates.Count) then
|
||||||
RaiseNotYetImplemented(20190912153602,ImplProc); // inconsistency
|
RaiseNotYetImplemented(20190912153602,ImplProc); // inconsistency
|
||||||
for i:=0 to ImplTemplates.Count-1 do
|
for i:=0 to ImplTemplates.Count-1 do
|
||||||
@ -15877,8 +15876,12 @@ var
|
|||||||
begin
|
begin
|
||||||
{$IF defined(VerbosePasResolver) or defined(VerbosePas2JS)}
|
{$IF defined(VerbosePasResolver) or defined(VerbosePas2JS)}
|
||||||
writeln('InsertBehind Generic=',GetObjName(GenericEl),' Last=',GetObjName(Last));
|
writeln('InsertBehind Generic=',GetObjName(GenericEl),' Last=',GetObjName(Last));
|
||||||
|
//for i:=0 to List.Count-1 do writeln(' ',GetObjName(TObject(List[i])));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
RaiseNotYetImplemented(20190826150507,El);
|
if GenericEl is TPasProcedure then
|
||||||
|
i:=List.Count-1
|
||||||
|
else
|
||||||
|
RaiseNotYetImplemented(20190826150507,El);
|
||||||
end;
|
end;
|
||||||
List.Insert(i+1,NewEl);
|
List.Insert(i+1,NewEl);
|
||||||
end;
|
end;
|
||||||
|
@ -6365,6 +6365,7 @@ function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
|
|||||||
): TPasProcedure;
|
): TPasProcedure;
|
||||||
var
|
var
|
||||||
NameParts: TProcedureNameParts;
|
NameParts: TProcedureNameParts;
|
||||||
|
NamePos: TPasSourcePos;
|
||||||
|
|
||||||
function ExpectProcName: string;
|
function ExpectProcName: string;
|
||||||
{ Simple procedure:
|
{ Simple procedure:
|
||||||
@ -6388,6 +6389,7 @@ var
|
|||||||
Part: TProcedureNamePart;
|
Part: TProcedureNamePart;
|
||||||
begin
|
begin
|
||||||
Result:=ExpectIdentifier;
|
Result:=ExpectIdentifier;
|
||||||
|
NamePos:=CurSourcePos;
|
||||||
Cnt:=1;
|
Cnt:=1;
|
||||||
repeat
|
repeat
|
||||||
NextToken;
|
NextToken;
|
||||||
@ -6397,6 +6399,7 @@ var
|
|||||||
begin
|
begin
|
||||||
inc(Cnt);
|
inc(Cnt);
|
||||||
CurName:=ExpectIdentifier;
|
CurName:=ExpectIdentifier;
|
||||||
|
NamePos:=CurSourcePos;
|
||||||
Result:=Result+'.'+CurName;
|
Result:=Result+'.'+CurName;
|
||||||
if NameParts<>nil then
|
if NameParts<>nil then
|
||||||
begin
|
begin
|
||||||
@ -6476,12 +6479,14 @@ begin
|
|||||||
if (ot=otUnknown) then
|
if (ot=otUnknown) then
|
||||||
ParseExc(nErrUnknownOperatorType,SErrUnknownOperatorType,[CurTokenString]);
|
ParseExc(nErrUnknownOperatorType,SErrUnknownOperatorType,[CurTokenString]);
|
||||||
Name:=OperatorNames[Ot];
|
Name:=OperatorNames[Ot];
|
||||||
|
NamePos:=CurTokenPos;
|
||||||
end;
|
end;
|
||||||
ptAnonymousProcedure,ptAnonymousFunction:
|
ptAnonymousProcedure,ptAnonymousFunction:
|
||||||
begin
|
begin
|
||||||
Name:='';
|
Name:='';
|
||||||
if MustBeGeneric then
|
if MustBeGeneric then
|
||||||
ParseExcTokenError('generic'); // inconsistency
|
ParseExcTokenError('generic'); // inconsistency
|
||||||
|
NamePos:=CurTokenPos;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Name:=ExpectProcName;
|
Name:=ExpectProcName;
|
||||||
@ -6490,7 +6495,7 @@ begin
|
|||||||
if Name<>'' then
|
if Name<>'' then
|
||||||
Parent:=CheckIfOverLoaded(Parent,Name);
|
Parent:=CheckIfOverLoaded(Parent,Name);
|
||||||
Result := TPasProcedure(Engine.CreateElement(PC, Name, Parent, AVisibility,
|
Result := TPasProcedure(Engine.CreateElement(PC, Name, Parent, AVisibility,
|
||||||
CurSourcePos, NameParts));
|
NamePos, NameParts));
|
||||||
if NameParts<>nil then
|
if NameParts<>nil then
|
||||||
begin
|
begin
|
||||||
if Result.NameParts=nil then
|
if Result.NameParts=nil then
|
||||||
|
@ -125,17 +125,21 @@ type
|
|||||||
procedure TestGenProc_MissingTemplatesFail;
|
procedure TestGenProc_MissingTemplatesFail;
|
||||||
procedure TestGenProc_Forward;
|
procedure TestGenProc_Forward;
|
||||||
procedure TestGenProc_External;
|
procedure TestGenProc_External;
|
||||||
//procedure TestGenProc_UnitIntf;
|
procedure TestGenProc_UnitIntf;
|
||||||
procedure TestGenProc_BackRef1Fail;
|
procedure TestGenProc_BackRef1Fail;
|
||||||
procedure TestGenProc_BackRef2Fail;
|
procedure TestGenProc_BackRef2Fail;
|
||||||
procedure TestGenProc_BackRef3Fail;
|
procedure TestGenProc_BackRef3Fail;
|
||||||
//procedure TestGenProc_Inference;
|
//procedure TestGenProc_Inference;
|
||||||
// ToDo: forward parametrized impl must not repeat constraints
|
procedure TestGenProc_CallSelf;
|
||||||
// ToDo: forward parametrized impl overloads
|
procedure TestGenProc_ForwardConstraints;
|
||||||
// ToDo: parametrized nested proc fail
|
procedure TestGenProc_ForwardConstraintsRepeatFail;
|
||||||
|
procedure TestGenProc_ForwardTempNameMismatch;
|
||||||
|
procedure TestGenProc_ForwardOverload;
|
||||||
|
procedure TestGenProc_NestedFail;
|
||||||
|
procedure TestGenMethod_VirtualFail;
|
||||||
// ToDo: virtual method cannot have type parameters
|
// ToDo: virtual method cannot have type parameters
|
||||||
// ToDo: message method cannot have type parameters
|
// ToDo: message method cannot have type parameters
|
||||||
// ToDo: interface method cannot have type parameters
|
// ToDo: class interface method cannot have type parameters
|
||||||
// ToDo: parametrized method mismatch interface method
|
// ToDo: parametrized method mismatch interface method
|
||||||
// ToDo: generic class method overload <T> <S,T>
|
// ToDo: generic class method overload <T> <S,T>
|
||||||
// ToDo: generic class method overload <T>(bool) <T>(word)
|
// ToDo: generic class method overload <T>(bool) <T>(word)
|
||||||
@ -1747,7 +1751,7 @@ begin
|
|||||||
'end;',
|
'end;',
|
||||||
'begin',
|
'begin',
|
||||||
'']);
|
'']);
|
||||||
CheckResolverException('Duplicate identifier "Fly" at afile.pp(2,25)',nDuplicateIdentifier);
|
CheckResolverException('Duplicate identifier "Fly" at afile.pp(2,22)',nDuplicateIdentifier);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestResolveGenerics.TestGenProc_MissingTemplatesFail;
|
procedure TTestResolveGenerics.TestGenProc_MissingTemplatesFail;
|
||||||
@ -1797,6 +1801,30 @@ begin
|
|||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenProc_UnitIntf;
|
||||||
|
begin
|
||||||
|
AddModuleWithIntfImplSrc('unit2.pas',
|
||||||
|
LinesToStr([
|
||||||
|
'generic function Fly<T>(a: T): T;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'generic function Fly<T>(a: T): T;',
|
||||||
|
'var i: T;',
|
||||||
|
'begin',
|
||||||
|
' i:=a;',
|
||||||
|
'end;',
|
||||||
|
'']));
|
||||||
|
StartProgram(true);
|
||||||
|
Add([
|
||||||
|
'uses unit2;',
|
||||||
|
'var w: word;',
|
||||||
|
'begin',
|
||||||
|
' w:=specialize Fly<word>(3);',
|
||||||
|
' if specialize Fly<boolean>(false) then ;',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestResolveGenerics.TestGenProc_BackRef1Fail;
|
procedure TTestResolveGenerics.TestGenProc_BackRef1Fail;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
@ -1833,6 +1861,131 @@ begin
|
|||||||
CheckResolverException('Wrong number of parameters specified for call to "function Fly<>(untyped)"',nWrongNumberOfParametersForCallTo);
|
CheckResolverException('Wrong number of parameters specified for call to "function Fly<>(untyped)"',nWrongNumberOfParametersForCallTo);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenProc_CallSelf;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'generic function Fly<T>(a: T): T;',
|
||||||
|
' procedure Run;',
|
||||||
|
' begin',
|
||||||
|
' specialize Fly<T>(a);',
|
||||||
|
' specialize Fly<word>(3);',
|
||||||
|
' end;',
|
||||||
|
'begin',
|
||||||
|
' specialize Fly<T>(a);',
|
||||||
|
' specialize Fly<boolean>(true);',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
' specialize Fly<string>(''fast'');',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenProc_ForwardConstraints;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'type',
|
||||||
|
' TObject = class end;',
|
||||||
|
' TBird = class end;',
|
||||||
|
'var b: TBird;',
|
||||||
|
'generic function Fly<T: class>(a: T): T; forward;',
|
||||||
|
'procedure Run;',
|
||||||
|
'begin',
|
||||||
|
' specialize Fly<TBird>(b);',
|
||||||
|
'end;',
|
||||||
|
'generic function Fly<T>(a: T): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
' specialize Fly<TBird>(b);',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenProc_ForwardConstraintsRepeatFail;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'type',
|
||||||
|
' TObject = class end;',
|
||||||
|
'generic function Fly<T: class>(a: T): T; forward;',
|
||||||
|
'generic function Fly<T: class>(a: T): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
CheckResolverException(sImplMustNotRepeatConstraints,nImplMustNotRepeatConstraints);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenProc_ForwardTempNameMismatch;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'generic function Fly<T>(a: T): T; forward;',
|
||||||
|
'generic function Fly<B>(a: B): B;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
CheckResolverException('Declaration of "Fly<B>" differs from previous declaration at afile.pp(2,23)',
|
||||||
|
nDeclOfXDiffersFromPrevAtY);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenProc_ForwardOverload;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'generic function {#FlyA}Fly<T>(a: T; b: boolean): T; forward; overload;',
|
||||||
|
'generic function {#FlyB}Fly<T>(a: T; w: word): T; forward; overload;',
|
||||||
|
'procedure {#FlyC}Fly; overload;',
|
||||||
|
'begin',
|
||||||
|
' specialize {@FlyA}Fly<longint>(1,true);',
|
||||||
|
' specialize {@FlyB}Fly<string>(''ABC'',3);',
|
||||||
|
'end;',
|
||||||
|
'generic function Fly<T>(a: T; b: boolean): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'generic function Fly<T>(a: T; w: word): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenProc_NestedFail;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'procedure Fly;',
|
||||||
|
' generic procedure Run<T>(a: T);',
|
||||||
|
' begin',
|
||||||
|
' end;',
|
||||||
|
'begin',
|
||||||
|
' Run<boolean>(true);',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
CheckResolverException('Type parameters not allowed on nested procedure',nTypeParamsNotAllowedOnX);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenMethod_VirtualFail;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'procedure Fly;',
|
||||||
|
' generic procedure Run<T>(a: T);',
|
||||||
|
' begin',
|
||||||
|
' end;',
|
||||||
|
'begin',
|
||||||
|
' Run<boolean>(true);',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
CheckResolverException('Type parameters not allowed on nested procedure',nTypeParamsNotAllowedOnX);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
RegisterTests([TTestResolveGenerics]);
|
RegisterTests([TTestResolveGenerics]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user