mirror of
https://gitlab.com/freepascal.org/fpc/pas2js.git
synced 2025-08-31 09:10:16 +02:00
fcl-passrc: resolver: error on using generic types without params
This commit is contained in:
parent
0bfef62666
commit
84321a4c29
@ -20904,11 +20904,27 @@ end;
|
|||||||
function TPasResolver.FindElementFor(const aName: String; AParent: TPasElement;
|
function TPasResolver.FindElementFor(const aName: String; AParent: TPasElement;
|
||||||
TypeParamCount: integer): TPasElement;
|
TypeParamCount: integer): TPasElement;
|
||||||
// called by TPasParser for direct types, e.g. type t = ns1.unit1.tobj.tsub
|
// called by TPasParser for direct types, e.g. type t = ns1.unit1.tobj.tsub
|
||||||
|
var
|
||||||
|
ErrorEl: TPasElement;
|
||||||
|
|
||||||
|
procedure CheckGenericRefWithoutParams(GenEl: TPasGenericType);
|
||||||
|
// called when TypeParamCount=0 check if reference to a generic type is allowed with
|
||||||
|
begin
|
||||||
|
if (GenEl.GenericTemplateTypes=nil) or (GenEl.GenericTemplateTypes.Count=0) then
|
||||||
|
exit;
|
||||||
|
// referrring to a generic type without params
|
||||||
|
if not (msDelphi in CurrentParser.CurrentModeswitches)
|
||||||
|
and (AParent<>nil)
|
||||||
|
and AParent.HasParent(GenEl) then
|
||||||
|
exit; // mode objfpc: inside the generic type it can be referred without params
|
||||||
|
RaiseMsg(20201129005025,nGenericsWithoutSpecializationAsType,sGenericsWithoutSpecializationAsType,['variable'],ErrorEl);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
p: SizeInt;
|
p: SizeInt;
|
||||||
RightPath, CurName, LeftPath: String;
|
RightPath, CurName, LeftPath: String;
|
||||||
NeedPop: Boolean;
|
NeedPop: Boolean;
|
||||||
CurScopeEl, NextEl, ErrorEl, BestEl: TPasElement;
|
CurScopeEl, NextEl, BestEl: TPasElement;
|
||||||
CurSection: TPasSection;
|
CurSection: TPasSection;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
UsesUnit: TPasUsesUnit;
|
UsesUnit: TPasUsesUnit;
|
||||||
@ -20980,11 +20996,17 @@ begin
|
|||||||
RaiseInternalError(20190801104033); // caller forgot to handle "With"
|
RaiseInternalError(20190801104033); // caller forgot to handle "With"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
begin
|
||||||
NextEl:=FindElementWithoutParams(CurName,ErrorEl,true,true);
|
NextEl:=FindElementWithoutParams(CurName,ErrorEl,true,true);
|
||||||
|
if (NextEl is TPasGenericType) and (RightPath='') then
|
||||||
|
CheckGenericRefWithoutParams(TPasGenericType(NextEl));
|
||||||
|
end;
|
||||||
{$IFDEF VerbosePasResolver}
|
{$IFDEF VerbosePasResolver}
|
||||||
//if RightPath<>'' then
|
//if RightPath<>'' then
|
||||||
// writeln('TPasResolver.FindElement searching scope "',CurName,'" RightPath="',RightPath,'" ... NextEl=',GetObjName(NextEl));
|
// writeln('TPasResolver.FindElement searching scope "',CurName,'" RightPath="',RightPath,'" ... NextEl=',GetObjName(NextEl));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
if NextEl=nil then
|
||||||
|
RaiseIdentifierNotFound(20201129004745,CurName,ErrorEl);
|
||||||
if NextEl is TPasModule then
|
if NextEl is TPasModule then
|
||||||
begin
|
begin
|
||||||
if CurScopeEl is TPasModule then
|
if CurScopeEl is TPasModule then
|
||||||
@ -21038,10 +21060,8 @@ begin
|
|||||||
else
|
else
|
||||||
CurScopeEl:=BestEl;
|
CurScopeEl:=BestEl;
|
||||||
end
|
end
|
||||||
else if NextEl<>nil then
|
|
||||||
CurScopeEl:=NextEl
|
|
||||||
else
|
else
|
||||||
RaiseIdentifierNotFound(20170328001941,CurName,ErrorEl);
|
CurScopeEl:=NextEl;
|
||||||
|
|
||||||
// restore scope
|
// restore scope
|
||||||
if NeedPop then
|
if NeedPop then
|
||||||
|
@ -64,6 +64,7 @@ type
|
|||||||
procedure TestGen_ClassObjFPC;
|
procedure TestGen_ClassObjFPC;
|
||||||
procedure TestGen_ClassObjFPC_OverloadFail;
|
procedure TestGen_ClassObjFPC_OverloadFail;
|
||||||
procedure TestGen_ClassObjFPC_OverloadOtherUnit;
|
procedure TestGen_ClassObjFPC_OverloadOtherUnit;
|
||||||
|
procedure TestGen_ClassGenAncestorWithoutParamFail;
|
||||||
procedure TestGen_ClassForward;
|
procedure TestGen_ClassForward;
|
||||||
procedure TestGen_ClassForwardConstraints;
|
procedure TestGen_ClassForwardConstraints;
|
||||||
procedure TestGen_ClassForwardConstraintNameMismatch;
|
procedure TestGen_ClassForwardConstraintNameMismatch;
|
||||||
@ -261,8 +262,8 @@ begin
|
|||||||
' TBirdAlias = TBird;',
|
' TBirdAlias = TBird;',
|
||||||
'begin',
|
'begin',
|
||||||
'']);
|
'']);
|
||||||
CheckResolverException('type expected, but TBird<> found',
|
CheckResolverException('Generics without specialization cannot be used as a type for a variable',
|
||||||
nXExpectedButYFound);
|
nGenericsWithoutSpecializationAsType);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestResolveGenerics.TestGen_TemplNameEqTypeNameFail;
|
procedure TTestResolveGenerics.TestGen_TemplNameEqTypeNameFail;
|
||||||
@ -940,6 +941,22 @@ begin
|
|||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGen_ClassGenAncestorWithoutParamFail;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$mode objfpc}',
|
||||||
|
'type',
|
||||||
|
' TObject = class end;',
|
||||||
|
' generic TBird<T> = class end;',
|
||||||
|
' generic TEagle<T> = class(TBird)',
|
||||||
|
' end;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
CheckResolverException('Generics without specialization cannot be used as a type for a variable',
|
||||||
|
nGenericsWithoutSpecializationAsType);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestResolveGenerics.TestGen_ClassForward;
|
procedure TTestResolveGenerics.TestGen_ClassForward;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
@ -16991,7 +16991,6 @@ begin
|
|||||||
' end;',
|
' end;',
|
||||||
'begin',
|
'begin',
|
||||||
' JSwiper.new;',
|
' JSwiper.new;',
|
||||||
//' if typeinfo(JSwiper)=nil then ;',
|
|
||||||
'']);
|
'']);
|
||||||
ConvertProgram;
|
ConvertProgram;
|
||||||
CheckSource('TestExternalClass_SameNamePublishedProperty',
|
CheckSource('TestExternalClass_SameNamePublishedProperty',
|
||||||
|
Loading…
Reference in New Issue
Block a user