mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 17:09:09 +02:00
pastojs: filer: local specialize type
git-svn-id: trunk@47134 -
This commit is contained in:
parent
201281ae2a
commit
79935d8579
@ -1009,6 +1009,8 @@ procedure TPasAnalyzer.MarkImplScopeRef(El, RefEl: TPasElement;
|
|||||||
|
|
||||||
if (RefEl.Name='') and not (RefEl is TInterfaceSection) then
|
if (RefEl.Name='') and not (RefEl is TInterfaceSection) then
|
||||||
exit; // reference to anonymous type -> not needed
|
exit; // reference to anonymous type -> not needed
|
||||||
|
if RefEl=ElImplScope.Element then
|
||||||
|
exit;
|
||||||
if ElImplScope is TPasProcedureScope then
|
if ElImplScope is TPasProcedureScope then
|
||||||
TPasProcedureScope(ElImplScope).AddReference(RefEl,Access)
|
TPasProcedureScope(ElImplScope).AddReference(RefEl,Access)
|
||||||
else if ElImplScope is TPasInitialFinalizationScope then
|
else if ElImplScope is TPasInitialFinalizationScope then
|
||||||
|
@ -942,6 +942,14 @@ type
|
|||||||
AddRef: TPCUAddRef;
|
AddRef: TPCUAddRef;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TPCUReaderPendingElScopeRef }
|
||||||
|
|
||||||
|
TPCUReaderPendingElScopeRef = class(TPCUFilerPendingElRef)
|
||||||
|
public
|
||||||
|
References: TPasScopeReferences;
|
||||||
|
Access: TPSRefAccess;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPCUReaderPendingIdentifierScope }
|
{ TPCUReaderPendingIdentifierScope }
|
||||||
|
|
||||||
TPCUReaderPendingIdentifierScope = class
|
TPCUReaderPendingIdentifierScope = class
|
||||||
@ -970,7 +978,7 @@ type
|
|||||||
GenericEl: TPasGenericType;
|
GenericEl: TPasGenericType;
|
||||||
Id: integer;
|
Id: integer;
|
||||||
Params: TFPList; // list of PCUReaderPendingSpecializedParams
|
Params: TFPList; // list of PCUReaderPendingSpecializedParams
|
||||||
RefEl: TPasElement; // a TInlineSpecializeExpr or TPasSpecializeType
|
RefEl: TPasElement; // a TInlineSpecializeExpr, TPasSpecializeType, TPasProcedure or TInitializationSection
|
||||||
SpecName: string;
|
SpecName: string;
|
||||||
Prev, Next: TPCUReaderPendingSpecialized;
|
Prev, Next: TPCUReaderPendingSpecialized;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -1024,7 +1032,7 @@ type
|
|||||||
function CreateSpecializedElement(PendSpec: TPCUReaderPendingSpecialized): boolean; // false=param missing
|
function CreateSpecializedElement(PendSpec: TPCUReaderPendingSpecialized): boolean; // false=param missing
|
||||||
procedure DeletePendingSpecialize(PendSpec: TPCUReaderPendingSpecialized);
|
procedure DeletePendingSpecialize(PendSpec: TPCUReaderPendingSpecialized);
|
||||||
procedure PromiseSpecialize(SpecId: integer; El: TPasElement; const SpecName: string); virtual;
|
procedure PromiseSpecialize(SpecId: integer; El: TPasElement; const SpecName: string); virtual;
|
||||||
procedure ResolveSpecializedElements;
|
procedure ResolveSpecializedElements(Complete: boolean);
|
||||||
protected
|
protected
|
||||||
// json
|
// json
|
||||||
procedure RaiseMsg(Id: int64; const Msg: string = ''); overload; override;
|
procedure RaiseMsg(Id: int64; const Msg: string = ''); overload; override;
|
||||||
@ -1047,8 +1055,11 @@ type
|
|||||||
AddRef: TPCUAddRef; ErrorEl: TPasElement); virtual;
|
AddRef: TPCUAddRef; ErrorEl: TPasElement); virtual;
|
||||||
procedure PromiseSetElArrReference(Id: integer; Arr: TPasElementArray; Index: integer;
|
procedure PromiseSetElArrReference(Id: integer; Arr: TPasElementArray; Index: integer;
|
||||||
AddRef: TPCUAddRef; ErrorEl: TPasElement); virtual;
|
AddRef: TPCUAddRef; ErrorEl: TPasElement); virtual;
|
||||||
|
procedure PromiseSetScopeReference(Id: integer; References: TPasScopeReferences;
|
||||||
|
Access: TPSRefAccess; ErrorEl: TPasElement); virtual;
|
||||||
procedure ResolvePendingIdentifierScopes; virtual;
|
procedure ResolvePendingIdentifierScopes; virtual;
|
||||||
procedure ResolvePending; virtual;
|
procedure ResolvePending(Complete: boolean); virtual;
|
||||||
|
function GetReferrerEl(PendingElRef: TPCUFilerPendingElRef): TPasElement;
|
||||||
procedure ReadBuiltInSymbols(Obj: TJSONObject; ErrorEl: TPasElement); virtual;
|
procedure ReadBuiltInSymbols(Obj: TJSONObject; ErrorEl: TPasElement); virtual;
|
||||||
// module
|
// module
|
||||||
procedure ReadHeaderMagic(Obj: TJSONObject); virtual;
|
procedure ReadHeaderMagic(Obj: TJSONObject); virtual;
|
||||||
@ -3309,7 +3320,8 @@ procedure TPCUWriter.WriteExtRefSignature(Ref: TPCUFilerElementRef;
|
|||||||
end;
|
end;
|
||||||
if Index<0 then
|
if Index<0 then
|
||||||
RaiseMsg(20180309184111,Member);
|
RaiseMsg(20180309184111,Member);
|
||||||
Obj.Add('MId',Index);
|
if Index>0 then
|
||||||
|
Obj.Add('MId',Index);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -5424,11 +5436,12 @@ function TPCUReader.CreateSpecializedElement(
|
|||||||
PendSpec: TPCUReaderPendingSpecialized): boolean;
|
PendSpec: TPCUReaderPendingSpecialized): boolean;
|
||||||
var
|
var
|
||||||
RefParams, ElParams: TFPList;
|
RefParams, ElParams: TFPList;
|
||||||
i: Integer;
|
i, Id: Integer;
|
||||||
SpecEl: TPasElement;
|
SpecEl: TPasElement;
|
||||||
Param: TPCUReaderPendingSpecializedParam;
|
Param: TPCUReaderPendingSpecializedParam;
|
||||||
Ref: TPCUFilerElementRef;
|
Ref: TPCUFilerElementRef;
|
||||||
Obj: TJSONObject;
|
Obj: TJSONObject;
|
||||||
|
GenericEl: TPasGenericType;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if PendSpec.RefEl=nil then
|
if PendSpec.RefEl=nil then
|
||||||
@ -5452,7 +5465,10 @@ begin
|
|||||||
if Param.Element<>nil then continue;
|
if Param.Element<>nil then continue;
|
||||||
Ref:=GetElReference(Param.Id,PendSpec.RefEl);
|
Ref:=GetElReference(Param.Id,PendSpec.RefEl);
|
||||||
if Ref=nil then
|
if Ref=nil then
|
||||||
|
begin
|
||||||
|
//writeln('TPCUReader.CreateSpecializedElement SpecName=',PendSpec.SpecName,' Id=',PendSpec.Id,' WAITING for param ',i,': ',Param.Id);
|
||||||
exit(false);
|
exit(false);
|
||||||
|
end;
|
||||||
Param.Element:=Ref.Element;
|
Param.Element:=Ref.Element;
|
||||||
end;
|
end;
|
||||||
// all RefParams resolved -> specialize
|
// all RefParams resolved -> specialize
|
||||||
@ -5460,8 +5476,11 @@ begin
|
|||||||
try
|
try
|
||||||
for i:=0 to RefParams.Count-1 do
|
for i:=0 to RefParams.Count-1 do
|
||||||
ElParams.Add(TPCUReaderPendingSpecializedParam(RefParams[i]).Element);
|
ElParams.Add(TPCUReaderPendingSpecializedParam(RefParams[i]).Element);
|
||||||
SpecEl:=Resolver.GetSpecializedEl(Resolver.RootElement,PendSpec.GenericEl,ElParams);
|
Id:=PendSpec.Id;
|
||||||
|
GenericEl:=PendSpec.GenericEl;
|
||||||
|
SpecEl:=Resolver.GetSpecializedEl(Resolver.RootElement,GenericEl,ElParams);
|
||||||
DeletePendingSpecialize(PendSpec);
|
DeletePendingSpecialize(PendSpec);
|
||||||
|
Ref:=AddElReference(Id,PendSpec.RefEl,SpecEl);
|
||||||
finally
|
finally
|
||||||
ElParams.Free;
|
ElParams.Free;
|
||||||
end;
|
end;
|
||||||
@ -5503,10 +5522,11 @@ begin
|
|||||||
PendSpec.RefEl:=El;
|
PendSpec.RefEl:=El;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPCUReader.ResolveSpecializedElements;
|
procedure TPCUReader.ResolveSpecializedElements(Complete: boolean);
|
||||||
var
|
var
|
||||||
PendSpec, NextPendSpec, UnresolvedSpec: TPCUReaderPendingSpecialized;
|
PendSpec, NextPendSpec, UnresolvedSpec: TPCUReaderPendingSpecialized;
|
||||||
Changed: Boolean;
|
Changed: Boolean;
|
||||||
|
Ref: TPCUFilerElementRef;
|
||||||
begin
|
begin
|
||||||
repeat
|
repeat
|
||||||
UnresolvedSpec:=nil;
|
UnresolvedSpec:=nil;
|
||||||
@ -5515,6 +5535,12 @@ begin
|
|||||||
while PendSpec<>nil do
|
while PendSpec<>nil do
|
||||||
begin
|
begin
|
||||||
NextPendSpec:=PendSpec.Next;
|
NextPendSpec:=PendSpec.Next;
|
||||||
|
if PendSpec.RefEl=nil then
|
||||||
|
begin
|
||||||
|
Ref:=GetElReference(PendSpec.Id,PendSpec.GenericEl);
|
||||||
|
if Ref<>nil then
|
||||||
|
PendSpec.RefEl:=GetReferrerEl(Ref.Pending);
|
||||||
|
end;
|
||||||
if PendSpec.RefEl<>nil then
|
if PendSpec.RefEl<>nil then
|
||||||
begin
|
begin
|
||||||
if CreateSpecializedElement(PendSpec) then
|
if CreateSpecializedElement(PendSpec) then
|
||||||
@ -5525,6 +5551,8 @@ begin
|
|||||||
PendSpec:=NextPendSpec;
|
PendSpec:=NextPendSpec;
|
||||||
end;
|
end;
|
||||||
until not Changed;
|
until not Changed;
|
||||||
|
if Complete then
|
||||||
|
UnresolvedSpec:=FPendingSpecialize;
|
||||||
if UnresolvedSpec<>nil then
|
if UnresolvedSpec<>nil then
|
||||||
// a pending specialize cannot resolve its params
|
// a pending specialize cannot resolve its params
|
||||||
RaiseMsg(20200531101924,UnresolvedSpec.GenericEl,UnresolvedSpec.SpecName+' Id='+IntToStr(UnresolvedSpec.Id)+' RefEl='+GetObjPath(UnresolvedSpec.RefEl));
|
RaiseMsg(20200531101924,UnresolvedSpec.GenericEl,UnresolvedSpec.SpecName+' Id='+IntToStr(UnresolvedSpec.Id)+' RefEl='+GetObjPath(UnresolvedSpec.RefEl));
|
||||||
@ -5717,6 +5745,7 @@ var
|
|||||||
PendingElArrRef: TPCUReaderPendingElArrRef;
|
PendingElArrRef: TPCUReaderPendingElArrRef;
|
||||||
{$IF defined(VerbosePCUFiler) or defined(memcheck)}
|
{$IF defined(VerbosePCUFiler) or defined(memcheck)}
|
||||||
Node: TAVLTreeNode;
|
Node: TAVLTreeNode;
|
||||||
|
PendingElScopeRef: TPCUReaderPendingElScopeRef;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
if Id<=0 then
|
if Id<=0 then
|
||||||
@ -5791,6 +5820,11 @@ begin
|
|||||||
if PendingElArrRef.AddRef{$IFDEF CheckPasTreeRefCount}<>''{$ENDIF} then
|
if PendingElArrRef.AddRef{$IFDEF CheckPasTreeRefCount}<>''{$ENDIF} then
|
||||||
Ref.Element.AddRef{$IFDEF CheckPasTreeRefCount}(PendingElArrRef.AddRef){$ENDIF};
|
Ref.Element.AddRef{$IFDEF CheckPasTreeRefCount}(PendingElArrRef.AddRef){$ENDIF};
|
||||||
end
|
end
|
||||||
|
else if RefItem is TPCUReaderPendingElScopeRef then
|
||||||
|
begin
|
||||||
|
PendingElScopeRef:=TPCUReaderPendingElScopeRef(RefItem);
|
||||||
|
PendingElScopeRef.References.Add(Ref.Element,PendingElScopeRef.Access);
|
||||||
|
end
|
||||||
else
|
else
|
||||||
RaiseMsg(20180207153056,ErrorEl,RefItem.ClassName);
|
RaiseMsg(20180207153056,ErrorEl,RefItem.ClassName);
|
||||||
Ref.Pending:=RefItem.Next;
|
Ref.Pending:=RefItem.Next;
|
||||||
@ -5879,6 +5913,29 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPCUReader.PromiseSetScopeReference(Id: integer;
|
||||||
|
References: TPasScopeReferences; Access: TPSRefAccess; ErrorEl: TPasElement);
|
||||||
|
var
|
||||||
|
Ref: TPCUFilerElementRef;
|
||||||
|
PendingItem: TPCUReaderPendingElScopeRef;
|
||||||
|
begin
|
||||||
|
Ref:=AddElReference(Id,ErrorEl,nil);
|
||||||
|
if Ref.Element<>nil then
|
||||||
|
begin
|
||||||
|
// element was already created -> add reference immediately
|
||||||
|
References.Add(Ref.Element,Access);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// element was not yet created -> store
|
||||||
|
PendingItem:=TPCUReaderPendingElScopeRef.Create;
|
||||||
|
PendingItem.References:=References;
|
||||||
|
PendingItem.Access:=Access;
|
||||||
|
PendingItem.ErrorEl:=ErrorEl;
|
||||||
|
Ref.AddPending(PendingItem);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPCUReader.ResolvePendingIdentifierScopes;
|
procedure TPCUReader.ResolvePendingIdentifierScopes;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -5892,14 +5949,13 @@ begin
|
|||||||
FPendingIdentifierScopes.Clear;
|
FPendingIdentifierScopes.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPCUReader.ResolvePending;
|
procedure TPCUReader.ResolvePending(Complete: boolean);
|
||||||
var
|
var
|
||||||
Node: TAVLTreeNode;
|
Node: TAVLTreeNode;
|
||||||
Ref: TPCUFilerElementRef;
|
Ref: TPCUFilerElementRef;
|
||||||
begin
|
begin
|
||||||
ResolvePendingIdentifierScopes;
|
ResolvePendingIdentifierScopes;
|
||||||
|
ResolveSpecializedElements(Complete);
|
||||||
ResolveSpecializedElements;
|
|
||||||
|
|
||||||
// check dangling references
|
// check dangling references
|
||||||
Node:=FElementRefs.FindLowest;
|
Node:=FElementRefs.FindLowest;
|
||||||
@ -5920,6 +5976,18 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPCUReader.GetReferrerEl(PendingElRef: TPCUFilerPendingElRef
|
||||||
|
): TPasElement;
|
||||||
|
begin
|
||||||
|
while PendingElRef<>nil do
|
||||||
|
begin
|
||||||
|
Result:=PendingElRef.ErrorEl;
|
||||||
|
if Result<>nil then exit;
|
||||||
|
PendingElRef:=PendingElRef.Next;
|
||||||
|
end;
|
||||||
|
Result:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPCUReader.ReadBuiltInSymbols(Obj: TJSONObject; ErrorEl: TPasElement);
|
procedure TPCUReader.ReadBuiltInSymbols(Obj: TJSONObject; ErrorEl: TPasElement);
|
||||||
var
|
var
|
||||||
Arr: TJSONArray;
|
Arr: TJSONArray;
|
||||||
@ -6432,7 +6500,12 @@ begin
|
|||||||
if not ReadString(SubObj,'Name',Name,El) then
|
if not ReadString(SubObj,'Name',Name,El) then
|
||||||
RaiseMsg(20180309180233,El,IntToStr(i));
|
RaiseMsg(20180309180233,El,IntToStr(i));
|
||||||
if not ReadInteger(SubObj,'MId',Index,El) then
|
if not ReadInteger(SubObj,'MId',Index,El) then
|
||||||
RaiseMsg(20180309184629,El,IntToStr(i));
|
begin
|
||||||
|
if SubObj.Find('MId')=nil then
|
||||||
|
Index:=0
|
||||||
|
else
|
||||||
|
RaiseMsg(20180309184629,El,IntToStr(i));
|
||||||
|
end;
|
||||||
if (Index<0) or (Index>=Members.Count) then
|
if (Index<0) or (Index>=Members.Count) then
|
||||||
RaiseMsg(20180309184718,El,IntToStr(Index)+' out of bounds 0-'+IntToStr(Members.Count));
|
RaiseMsg(20180309184718,El,IntToStr(Index)+' out of bounds 0-'+IntToStr(Members.Count));
|
||||||
ChildEl:=nil;
|
ChildEl:=nil;
|
||||||
@ -6492,6 +6565,7 @@ var
|
|||||||
PendSpec: TPCUReaderPendingSpecialized;
|
PendSpec: TPCUReaderPendingSpecialized;
|
||||||
PendParam: TPCUReaderPendingSpecializedParam;
|
PendParam: TPCUReaderPendingSpecializedParam;
|
||||||
SpecName: string;
|
SpecName: string;
|
||||||
|
Ref: TPCUFilerElementRef;
|
||||||
begin
|
begin
|
||||||
ErrorEl:=GenEl;
|
ErrorEl:=GenEl;
|
||||||
if ParamIDs.Count=0 then
|
if ParamIDs.Count=0 then
|
||||||
@ -6505,6 +6579,9 @@ begin
|
|||||||
PendSpec.Obj:=Obj;
|
PendSpec.Obj:=Obj;
|
||||||
PendSpec.GenericEl:=GenEl;
|
PendSpec.GenericEl:=GenEl;
|
||||||
|
|
||||||
|
Ref:=AddElReference(Id,GenEl,nil);
|
||||||
|
Ref.Obj:=Obj;
|
||||||
|
|
||||||
PendSpec.Params:=TFPList.Create;
|
PendSpec.Params:=TFPList.Create;
|
||||||
for i:=0 to ParamIDs.Count-1 do
|
for i:=0 to ParamIDs.Count-1 do
|
||||||
begin
|
begin
|
||||||
@ -6743,7 +6820,7 @@ begin
|
|||||||
Scope.Finished:=true;
|
Scope.Finished:=true;
|
||||||
if Section is TInterfaceSection then
|
if Section is TInterfaceSection then
|
||||||
begin
|
begin
|
||||||
ResolvePending;
|
ResolvePending(false);
|
||||||
Resolver.NotifyPendingUsedInterfaces;
|
Resolver.NotifyPendingUsedInterfaces;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -7219,7 +7296,6 @@ var
|
|||||||
i, Id: Integer;
|
i, Id: Integer;
|
||||||
Data: TJSONData;
|
Data: TJSONData;
|
||||||
SubObj: TJSONObject;
|
SubObj: TJSONObject;
|
||||||
Ref: TPCUFilerElementRef;
|
|
||||||
s: string;
|
s: string;
|
||||||
Found: Boolean;
|
Found: Boolean;
|
||||||
Access: TPSRefAccess;
|
Access: TPSRefAccess;
|
||||||
@ -7239,12 +7315,6 @@ begin
|
|||||||
Data:=SubObj.Find('Id');
|
Data:=SubObj.Find('Id');
|
||||||
if not (Data is TJSONIntegerNumber) then
|
if not (Data is TJSONIntegerNumber) then
|
||||||
RaiseMsg(20180221171546,El,GetObjName(Data));
|
RaiseMsg(20180221171546,El,GetObjName(Data));
|
||||||
Id:=Data.AsInteger;
|
|
||||||
Ref:=GetElReference(Id,El);
|
|
||||||
if Ref=nil then
|
|
||||||
RaiseMsg(20180221171940,El,IntToStr(Id));
|
|
||||||
if Ref.Element=nil then
|
|
||||||
RaiseMsg(20180221171940,El,IntToStr(Id));
|
|
||||||
if ReadString(SubObj,'Access',s,El) then
|
if ReadString(SubObj,'Access',s,El) then
|
||||||
begin
|
begin
|
||||||
Found:=false;
|
Found:=false;
|
||||||
@ -7259,7 +7329,8 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
Access:=PCUDefaultPSRefAccess;
|
Access:=PCUDefaultPSRefAccess;
|
||||||
References.Add(Ref.Element,Access);
|
Id:=Data.AsInteger;
|
||||||
|
PromiseSetScopeReference(Id,References,Access,El);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -7904,7 +7975,7 @@ begin
|
|||||||
aContext.ModeSwitches:=OldModeSwitches;
|
aContext.ModeSwitches:=OldModeSwitches;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ResolvePending;
|
ResolvePending(true);
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -218,11 +218,9 @@ type
|
|||||||
procedure TestPC_GenericFunction_AnonymousProc;
|
procedure TestPC_GenericFunction_AnonymousProc;
|
||||||
procedure TestPC_GenericClass;
|
procedure TestPC_GenericClass;
|
||||||
procedure TestPC_GenericMethod;
|
procedure TestPC_GenericMethod;
|
||||||
procedure TestPC_SpecializeClassSameUnit; // ToDo
|
procedure TestPC_SpecializeClassSameUnit;
|
||||||
// ToDo: specialize local generic type in unit interface
|
procedure TestPC_Specialize_LocalTypeInUnit;
|
||||||
// ToDo: specialize local generic type in unit implementation
|
// ToDo: specialize local generic type via class forward
|
||||||
// ToDo: specialize local generic type in proc decl
|
|
||||||
// ToDo: specialize local generic type in proc body
|
|
||||||
// ToDo: inline specialize local generic type in unit interface
|
// ToDo: inline specialize local generic type in unit interface
|
||||||
// ToDo: inline specialize local generic type in unit implementation
|
// ToDo: inline specialize local generic type in unit implementation
|
||||||
// ToDo: inline specialize local generic type in proc decl
|
// ToDo: inline specialize local generic type in proc decl
|
||||||
@ -691,21 +689,21 @@ begin
|
|||||||
SubPath:=SubPath+'?noname?';
|
SubPath:=SubPath+'?noname?';
|
||||||
// search specialization with same name
|
// search specialization with same name
|
||||||
RestIndex:=0;
|
RestIndex:=0;
|
||||||
while RestIndex<Rest.Declarations.Count do
|
repeat
|
||||||
begin
|
if RestIndex=Rest.Declarations.Count then
|
||||||
|
Fail(SubPath+' missing in restored Declarations');
|
||||||
RestDecl:=TPasElement(Rest.Declarations[RestIndex]);
|
RestDecl:=TPasElement(Rest.Declarations[RestIndex]);
|
||||||
if IsSpecialization(RestDecl) and (OrigDecl.Name=RestDecl.Name) then
|
if IsSpecialization(RestDecl) and (OrigDecl.Name=RestDecl.Name) then
|
||||||
break;
|
break;
|
||||||
inc(RestIndex);
|
inc(RestIndex);
|
||||||
end;
|
until false;
|
||||||
if RestIndex=Rest.Declarations.Count then
|
|
||||||
Fail(SubPath+' missing in restored Declarations');
|
if (OrigIndex<Rest.Declarations.Count) and (OrigIndex<>RestIndex) then
|
||||||
|
// move restored element to original place to generate the same JS
|
||||||
|
Rest.Declarations.Move(RestIndex,OrigIndex);
|
||||||
|
|
||||||
// check
|
// check
|
||||||
CheckRestoredElement(SubPath,OrigDecl,RestDecl,Flags);
|
CheckRestoredElement(SubPath,OrigDecl,RestDecl,Flags);
|
||||||
|
|
||||||
// move restored element to original place to generate the same JS
|
|
||||||
if OrigIndex<Rest.Declarations.Count then
|
|
||||||
Rest.Declarations.Move(RestIndex,OrigIndex);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
AssertEquals(Path+'.Declarations.Count',Orig.Declarations.Count,Rest.Declarations.Count);
|
AssertEquals(Path+'.Declarations.Count',Orig.Declarations.Count,Rest.Declarations.Count);
|
||||||
@ -1026,12 +1024,14 @@ var
|
|||||||
OrigList, RestList: TFPList;
|
OrigList, RestList: TFPList;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
OrigRef, RestRef: TPasScopeReference;
|
OrigRef, RestRef: TPasScopeReference;
|
||||||
|
ok: Boolean;
|
||||||
begin
|
begin
|
||||||
if Flags=[] then ;
|
if Flags=[] then ;
|
||||||
CheckRestoredObject(Path,Orig,Rest);
|
CheckRestoredObject(Path,Orig,Rest);
|
||||||
if Orig=nil then exit;
|
if Orig=nil then exit;
|
||||||
OrigList:=nil;
|
OrigList:=nil;
|
||||||
RestList:=nil;
|
RestList:=nil;
|
||||||
|
ok:=false;
|
||||||
try
|
try
|
||||||
OrigList:=Orig.GetList;
|
OrigList:=Orig.GetList;
|
||||||
RestList:=Rest.GetList;
|
RestList:=Rest.GetList;
|
||||||
@ -1054,7 +1054,21 @@ begin
|
|||||||
RestRef:=TPasScopeReference(RestList[i]);
|
RestRef:=TPasScopeReference(RestList[i]);
|
||||||
Fail(Path+'['+IntToStr(i)+'] Too many in Rest: "'+RestRef.Element.Name+'"');
|
Fail(Path+'['+IntToStr(i)+'] Too many in Rest: "'+RestRef.Element.Name+'"');
|
||||||
end;
|
end;
|
||||||
|
ok:=true;
|
||||||
finally
|
finally
|
||||||
|
if not ok then
|
||||||
|
begin
|
||||||
|
for i:=0 to OrigList.Count-1 do
|
||||||
|
begin
|
||||||
|
OrigRef:=TPasScopeReference(OrigList[i]);
|
||||||
|
writeln('TCustomTestPrecompile.CheckRestoredScopeRefs Orig[',i,']=',GetObjPath(OrigRef.Element));
|
||||||
|
end;
|
||||||
|
for i:=0 to RestList.Count-1 do
|
||||||
|
begin
|
||||||
|
RestRef:=TPasScopeReference(RestList[i]);
|
||||||
|
writeln('TCustomTestPrecompile.CheckRestoredScopeRefs Rest[',i,']=',GetObjPath(RestRef.Element));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
OrigList.Free;
|
OrigList.Free;
|
||||||
RestList.Free;
|
RestList.Free;
|
||||||
end;
|
end;
|
||||||
@ -1264,7 +1278,14 @@ begin
|
|||||||
if RestUsed=nil then
|
if RestUsed=nil then
|
||||||
Fail(Path+': used in OrigAnalyzer, but not used in RestAnalyzer');
|
Fail(Path+': used in OrigAnalyzer, but not used in RestAnalyzer');
|
||||||
if OrigUsed.Access<>RestUsed.Access then
|
if OrigUsed.Access<>RestUsed.Access then
|
||||||
AssertEquals(Path+'->Analyzer.Access',dbgs(OrigUsed.Access),dbgs(RestUsed.Access));
|
begin
|
||||||
|
if (OrigUsed.Access in [paiaReadWrite,paiaWriteRead])
|
||||||
|
and (RestUsed.Access in [paiaReadWrite,paiaWriteRead])
|
||||||
|
and not (Orig.Parent is TProcedureBody) then
|
||||||
|
// readwrite or writeread is irrelevant for globals
|
||||||
|
else
|
||||||
|
AssertEquals(Path+'->Analyzer.Access',dbgs(OrigUsed.Access),dbgs(RestUsed.Access));
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else if RestAnalyzer.IsUsed(Rest) then
|
else if RestAnalyzer.IsUsed(Rest) then
|
||||||
begin
|
begin
|
||||||
@ -3204,7 +3225,46 @@ begin
|
|||||||
'implementation',
|
'implementation',
|
||||||
'begin',
|
'begin',
|
||||||
' b.a:=1.3;',
|
' b.a:=1.3;',
|
||||||
'end.',
|
'']);
|
||||||
|
WriteReadUnit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPrecompile.TestPC_Specialize_LocalTypeInUnit;
|
||||||
|
begin
|
||||||
|
StartUnit(false);
|
||||||
|
Add([
|
||||||
|
'{$mode delphi}',
|
||||||
|
'interface',
|
||||||
|
'type',
|
||||||
|
' TObject = class',
|
||||||
|
' end;',
|
||||||
|
' TBird<T> = class',
|
||||||
|
' a: T;',
|
||||||
|
' end;',
|
||||||
|
//' TDoubleBird = TBIrd<double>;',
|
||||||
|
//'var',
|
||||||
|
//' db: TDoubleBird;',
|
||||||
|
'procedure Fly;',
|
||||||
|
'implementation',
|
||||||
|
'type',
|
||||||
|
' TWordBird = TBird<word>;',
|
||||||
|
'procedure Run;',
|
||||||
|
//'type TShortIntBird = TBird<shortint>;',
|
||||||
|
'var',
|
||||||
|
//' shb: TShortIntBird;',
|
||||||
|
' wb: TWordBird;',
|
||||||
|
'begin',
|
||||||
|
//' shb.a:=3;',
|
||||||
|
' wb.a:=4;',
|
||||||
|
'end;',
|
||||||
|
'procedure Fly;',
|
||||||
|
//'type TByteBird = TBird<byte>;',
|
||||||
|
//'var bb: TByteBird;',
|
||||||
|
'begin',
|
||||||
|
//' bb.a:=5;',
|
||||||
|
' Run;',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
'']);
|
'']);
|
||||||
WriteReadUnit;
|
WriteReadUnit;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user