|
@@ -964,7 +964,10 @@ type
|
|
public
|
|
public
|
|
Obj: TJSONObject;
|
|
Obj: TJSONObject;
|
|
GenericEl: TPasGenericType;
|
|
GenericEl: TPasGenericType;
|
|
|
|
+ Id: integer;
|
|
Params: TFPList; // list of PCUReaderPendingSpecializedParams
|
|
Params: TFPList; // list of PCUReaderPendingSpecializedParams
|
|
|
|
+ RefEl: TPasElement; // a TInlineSpecializeExpr or TPasSpecializeType
|
|
|
|
+ SpecName: string;
|
|
Prev, Next: TPCUReaderPendingSpecialized;
|
|
Prev, Next: TPCUReaderPendingSpecialized;
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
end;
|
|
end;
|
|
@@ -976,9 +979,6 @@ type
|
|
FElementRefsArray: TPCUFilerElementRefArray; // TPCUFilerElementRef by Id
|
|
FElementRefsArray: TPCUFilerElementRefArray; // TPCUFilerElementRef by Id
|
|
FJSON: TJSONObject;
|
|
FJSON: TJSONObject;
|
|
FPendingIdentifierScopes: TObjectList; // list of TPCUReaderPendingIdentifierScope
|
|
FPendingIdentifierScopes: TObjectList; // list of TPCUReaderPendingIdentifierScope
|
|
- FPendingSpecialize: TPCUReaderPendingSpecialized; // chain of TPCUReaderPendingSpecialized
|
|
|
|
- function AddPendingSpecialize(GenEl: TPasGenericType; ParamCount: integer): TPCUReaderPendingSpecialized;
|
|
|
|
- procedure DeletePendingSpecialize(PendSpec: TPCUReaderPendingSpecialized);
|
|
|
|
procedure Set_Variable_VarType(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_Variable_VarType(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_AliasType_DestType(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_AliasType_DestType(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_PointerType_DestType(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_PointerType_DestType(RefEl: TPasElement; Data: TObject);
|
|
@@ -1012,8 +1012,15 @@ type
|
|
procedure Set_ResolvedReference_Declaration(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_ResolvedReference_Declaration(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_ResolvedReference_CtxConstructor(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_ResolvedReference_CtxConstructor(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_ResolvedReference_CtxAttrProc(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_ResolvedReference_CtxAttrProc(RefEl: TPasElement; Data: TObject);
|
|
- procedure Set_SpecializeParam(RefEl: TPasElement; Data: TObject);
|
|
|
|
procedure Set_SpecializeTypeData(RefEl: TPasElement; Data: TObject);
|
|
procedure Set_SpecializeTypeData(RefEl: TPasElement; Data: TObject);
|
|
|
|
+ protected
|
|
|
|
+ // specialize
|
|
|
|
+ FPendingSpecialize: TPCUReaderPendingSpecialized; // chain of TPCUReaderPendingSpecialized
|
|
|
|
+ function AddPendingSpecialize(Id: integer; const SpecName: string): TPCUReaderPendingSpecialized;
|
|
|
|
+ function CreateSpecializedElement(PendSpec: TPCUReaderPendingSpecialized): boolean; // false=param missing
|
|
|
|
+ procedure DeletePendingSpecialize(PendSpec: TPCUReaderPendingSpecialized);
|
|
|
|
+ procedure PromiseSpecialize(SpecId: integer; El: TPasElement; const SpecName: string); virtual;
|
|
|
|
+ procedure ResolveSpecializedElements;
|
|
protected
|
|
protected
|
|
// json
|
|
// json
|
|
procedure RaiseMsg(Id: int64; const Msg: string = ''); overload; override;
|
|
procedure RaiseMsg(Id: int64; const Msg: string = ''); overload; override;
|
|
@@ -1036,7 +1043,7 @@ 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 PromiseSpecialize(SpecId: integer; El: TPasElement; const SpecName: string); virtual;
|
|
|
|
|
|
+ procedure ResolvePendingIdentifierScopes; virtual;
|
|
procedure ResolvePending; virtual;
|
|
procedure ResolvePending; virtual;
|
|
procedure ReadBuiltInSymbols(Obj: TJSONObject; ErrorEl: TPasElement); virtual;
|
|
procedure ReadBuiltInSymbols(Obj: TJSONObject; ErrorEl: TPasElement); virtual;
|
|
// module
|
|
// module
|
|
@@ -4952,43 +4959,6 @@ end;
|
|
|
|
|
|
{ TPCUReader }
|
|
{ TPCUReader }
|
|
|
|
|
|
-function TPCUReader.AddPendingSpecialize(GenEl: TPasGenericType;
|
|
|
|
- ParamCount: integer): TPCUReaderPendingSpecialized;
|
|
|
|
-var
|
|
|
|
- Param: TPCUReaderPendingSpecializedParam;
|
|
|
|
- i: Integer;
|
|
|
|
-begin
|
|
|
|
- Result:=TPCUReaderPendingSpecialized.Create;
|
|
|
|
- Result.GenericEl:=GenEl;
|
|
|
|
- if FPendingSpecialize<>nil then
|
|
|
|
- begin
|
|
|
|
- Result.Next:=FPendingSpecialize;
|
|
|
|
- FPendingSpecialize.Prev:=Result;
|
|
|
|
- end;
|
|
|
|
- FPendingSpecialize:=Result;
|
|
|
|
-
|
|
|
|
- Result.Params:=TFPList.Create;
|
|
|
|
- for i:=0 to ParamCount-1 do
|
|
|
|
- begin
|
|
|
|
- Param:=TPCUReaderPendingSpecializedParam.Create;
|
|
|
|
- Result.Params.Add(Param);
|
|
|
|
- Param.Spec:=Result;
|
|
|
|
- Param.Index:=i;
|
|
|
|
- end;
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
-procedure TPCUReader.DeletePendingSpecialize(
|
|
|
|
- PendSpec: TPCUReaderPendingSpecialized);
|
|
|
|
-begin
|
|
|
|
- if FPendingSpecialize=PendSpec then
|
|
|
|
- FPendingSpecialize:=PendSpec.Next;
|
|
|
|
- if PendSpec.Prev<>nil then PendSpec.Prev.Next:=PendSpec.Next;
|
|
|
|
- if PendSpec.Next<>nil then PendSpec.Next.Prev:=PendSpec.Prev;
|
|
|
|
- PendSpec.Prev:=nil;
|
|
|
|
- PendSpec.Next:=nil;
|
|
|
|
- PendSpec.Free;
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
procedure TPCUReader.Set_Variable_VarType(RefEl: TPasElement; Data: TObject);
|
|
procedure TPCUReader.Set_Variable_VarType(RefEl: TPasElement; Data: TObject);
|
|
var
|
|
var
|
|
El: TPasVariable absolute Data;
|
|
El: TPasVariable absolute Data;
|
|
@@ -5406,44 +5376,138 @@ begin
|
|
RaiseMsg(20190222010821,Ref.Element,GetObjPath(RefEl));
|
|
RaiseMsg(20190222010821,Ref.Element,GetObjPath(RefEl));
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TPCUReader.Set_SpecializeParam(RefEl: TPasElement; Data: TObject);
|
|
|
|
|
|
+procedure TPCUReader.Set_SpecializeTypeData(RefEl: TPasElement; Data: TObject);
|
|
|
|
+var
|
|
|
|
+ SpecData: TPasSpecializeTypeData absolute Data;
|
|
|
|
+begin
|
|
|
|
+ if RefEl is TPasGenericType then
|
|
|
|
+ SpecData.SpecializedType:=TPasGenericType(RefEl) // no AddRef
|
|
|
|
+ else
|
|
|
|
+ RaiseMsg(20200514130809,SpecData.Element,GetObjPath(RefEl));
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPCUReader.AddPendingSpecialize(Id: integer; const SpecName: string
|
|
|
|
+ ): TPCUReaderPendingSpecialized;
|
|
|
|
+begin
|
|
|
|
+ Result:=TPCUReaderPendingSpecialized.Create;
|
|
|
|
+ if FPendingSpecialize<>nil then
|
|
|
|
+ begin
|
|
|
|
+ Result.Next:=FPendingSpecialize;
|
|
|
|
+ FPendingSpecialize.Prev:=Result;
|
|
|
|
+ end;
|
|
|
|
+ Result.Id:=Id;
|
|
|
|
+ Result.SpecName:=SpecName;
|
|
|
|
+ FPendingSpecialize:=Result;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPCUReader.CreateSpecializedElement(
|
|
|
|
+ PendSpec: TPCUReaderPendingSpecialized): boolean;
|
|
var
|
|
var
|
|
- Param: TPCUReaderPendingSpecializedParam absolute Data;
|
|
|
|
- PendSpec: TPCUReaderPendingSpecialized;
|
|
|
|
- i: Integer;
|
|
|
|
RefParams, ElParams: TFPList;
|
|
RefParams, ElParams: TFPList;
|
|
|
|
+ i: Integer;
|
|
SpecEl: TPasElement;
|
|
SpecEl: TPasElement;
|
|
|
|
+ Param: TPCUReaderPendingSpecializedParam;
|
|
|
|
+ Ref: TPCUFilerElementRef;
|
|
|
|
+ Obj: TJSONObject;
|
|
begin
|
|
begin
|
|
- PendSpec:=Param.Spec;
|
|
|
|
- if not (RefEl is TPasType) then
|
|
|
|
- RaiseMsg(20200222195932,PendSpec.GenericEl,GetObjPath(RefEl));
|
|
|
|
- Param.Element:=RefEl;
|
|
|
|
|
|
+ Result:=false;
|
|
|
|
+ if PendSpec.RefEl=nil then
|
|
|
|
+ begin
|
|
|
|
+ if PendSpec.GenericEl=nil then
|
|
|
|
+ RaiseMsg(20200531101241,PendSpec.SpecName)
|
|
|
|
+ else
|
|
|
|
+ RaiseMsg(20200531101105,PendSpec.GenericEl);// nothing uses this specialize
|
|
|
|
+ end;
|
|
|
|
+ if PendSpec.GenericEl=nil then
|
|
|
|
+ RaiseMsg(20200531101333,PendSpec.RefEl);
|
|
|
|
+ Obj:=PendSpec.Obj;
|
|
|
|
+ if Obj=nil then
|
|
|
|
+ RaiseMsg(20200531101128,PendSpec.GenericEl); // specialize missing in JSON
|
|
|
|
+
|
|
|
|
+ // resolve params
|
|
RefParams:=PendSpec.Params;
|
|
RefParams:=PendSpec.Params;
|
|
- i:=RefParams.Count-1;
|
|
|
|
- while (i>=0) and (TPCUReaderPendingSpecializedParam(RefParams[i]).Element<>nil) do
|
|
|
|
- dec(i);
|
|
|
|
- if i>=0 then exit;
|
|
|
|
|
|
+ for i:=0 to RefParams.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ Param:=TPCUReaderPendingSpecializedParam(RefParams[i]);
|
|
|
|
+ if Param.Element<>nil then continue;
|
|
|
|
+ Ref:=GetElReference(Param.Id,PendSpec.RefEl);
|
|
|
|
+ if Ref=nil then
|
|
|
|
+ exit(false);
|
|
|
|
+ Param.Element:=Ref.Element;
|
|
|
|
+ end;
|
|
// all RefParams resolved -> specialize
|
|
// all RefParams resolved -> specialize
|
|
ElParams:=TFPList.Create;
|
|
ElParams:=TFPList.Create;
|
|
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);
|
|
SpecEl:=Resolver.GetSpecializedEl(Resolver.RootElement,PendSpec.GenericEl,ElParams);
|
|
|
|
+ DeletePendingSpecialize(PendSpec);
|
|
finally
|
|
finally
|
|
ElParams.Free;
|
|
ElParams.Free;
|
|
end;
|
|
end;
|
|
// read child declarations
|
|
// read child declarations
|
|
- ReadExternalReferences(PendSpec.Obj,SpecEl);
|
|
|
|
|
|
+ ReadExternalReferences(Obj,SpecEl);
|
|
|
|
+ Result:=true;
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TPCUReader.Set_SpecializeTypeData(RefEl: TPasElement; Data: TObject);
|
|
|
|
|
|
+procedure TPCUReader.DeletePendingSpecialize(
|
|
|
|
+ PendSpec: TPCUReaderPendingSpecialized);
|
|
|
|
+begin
|
|
|
|
+ if FPendingSpecialize=PendSpec then
|
|
|
|
+ FPendingSpecialize:=PendSpec.Next;
|
|
|
|
+ if PendSpec.Prev<>nil then PendSpec.Prev.Next:=PendSpec.Next;
|
|
|
|
+ if PendSpec.Next<>nil then PendSpec.Next.Prev:=PendSpec.Prev;
|
|
|
|
+ PendSpec.Prev:=nil;
|
|
|
|
+ PendSpec.Next:=nil;
|
|
|
|
+ PendSpec.Free;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPCUReader.PromiseSpecialize(SpecId: integer; El: TPasElement;
|
|
|
|
+ const SpecName: string);
|
|
var
|
|
var
|
|
- SpecData: TPasSpecializeTypeData absolute Data;
|
|
|
|
|
|
+ PendSpec: TPCUReaderPendingSpecialized;
|
|
begin
|
|
begin
|
|
- if RefEl is TPasGenericType then
|
|
|
|
- SpecData.SpecializedType:=TPasGenericType(RefEl) // no AddRef
|
|
|
|
- else
|
|
|
|
- RaiseMsg(20200514130809,SpecData.Element,GetObjPath(RefEl));
|
|
|
|
|
|
+ PendSpec:=FPendingSpecialize;
|
|
|
|
+ while PendSpec<>nil do
|
|
|
|
+ begin
|
|
|
|
+ if PendSpec.Id=SpecId then
|
|
|
|
+ break;
|
|
|
|
+ PendSpec:=PendSpec.Next;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if PendSpec=nil then
|
|
|
|
+ PendSpec:=AddPendingSpecialize(SpecId,SpecName)
|
|
|
|
+ else if PendSpec.SpecName<>SpecName then
|
|
|
|
+ RaiseMsg(20200531093342,El,'Id='+IntToStr(SpecId)+' Expected SpecName "'+SpecName+'", but was "'+PendSpec.SpecName+'"');
|
|
|
|
+ if PendSpec.RefEl=nil then
|
|
|
|
+ PendSpec.RefEl:=El;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPCUReader.ResolveSpecializedElements;
|
|
|
|
+var
|
|
|
|
+ PendSpec, NextPendSpec, UnresolvedSpec: TPCUReaderPendingSpecialized;
|
|
|
|
+ Changed: Boolean;
|
|
|
|
+begin
|
|
|
|
+ repeat
|
|
|
|
+ UnresolvedSpec:=nil;
|
|
|
|
+ Changed:=false;
|
|
|
|
+ PendSpec:=FPendingSpecialize;
|
|
|
|
+ while PendSpec<>nil do
|
|
|
|
+ begin
|
|
|
|
+ NextPendSpec:=PendSpec.Next;
|
|
|
|
+ if PendSpec.RefEl<>nil then
|
|
|
|
+ begin
|
|
|
|
+ if CreateSpecializedElement(PendSpec) then
|
|
|
|
+ Changed:=true
|
|
|
|
+ else
|
|
|
|
+ UnresolvedSpec:=PendSpec;
|
|
|
|
+ end;
|
|
|
|
+ PendSpec:=NextPendSpec;
|
|
|
|
+ end;
|
|
|
|
+ until not Changed;
|
|
|
|
+ if UnresolvedSpec<>nil then
|
|
|
|
+ // a pending specialize cannot resolve its params
|
|
|
|
+ RaiseMsg(20200531101924,UnresolvedSpec.GenericEl,UnresolvedSpec.SpecName+' Id='+IntToStr(UnresolvedSpec.Id)+' RefEl='+GetObjPath(UnresolvedSpec.RefEl));
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TPCUReader.RaiseMsg(Id: int64; const Msg: string);
|
|
procedure TPCUReader.RaiseMsg(Id: int64; const Msg: string);
|
|
@@ -5795,19 +5859,10 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TPCUReader.PromiseSpecialize(SpecId: integer; El: TPasElement;
|
|
|
|
- const SpecName: string);
|
|
|
|
-begin
|
|
|
|
- // ToDo: add to list, specialize when unit interface/impl has finished, resolve nested references
|
|
|
|
- RaiseMsg(20200530134408,El,IntToStr(SpecId)+'='+SpecName);
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
-procedure TPCUReader.ResolvePending;
|
|
|
|
|
|
+procedure TPCUReader.ResolvePendingIdentifierScopes;
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
PendingIdentifierScope: TPCUReaderPendingIdentifierScope;
|
|
PendingIdentifierScope: TPCUReaderPendingIdentifierScope;
|
|
- Node: TAVLTreeNode;
|
|
|
|
- Ref: TPCUFilerElementRef;
|
|
|
|
begin
|
|
begin
|
|
for i:=0 to FPendingIdentifierScopes.Count-1 do
|
|
for i:=0 to FPendingIdentifierScopes.Count-1 do
|
|
begin
|
|
begin
|
|
@@ -5815,7 +5870,18 @@ begin
|
|
ReadIdentifierScopeArray(PendingIdentifierScope.Arr,PendingIdentifierScope.Scope);
|
|
ReadIdentifierScopeArray(PendingIdentifierScope.Arr,PendingIdentifierScope.Scope);
|
|
end;
|
|
end;
|
|
FPendingIdentifierScopes.Clear;
|
|
FPendingIdentifierScopes.Clear;
|
|
|
|
+end;
|
|
|
|
|
|
|
|
+procedure TPCUReader.ResolvePending;
|
|
|
|
+var
|
|
|
|
+ Node: TAVLTreeNode;
|
|
|
|
+ Ref: TPCUFilerElementRef;
|
|
|
|
+begin
|
|
|
|
+ ResolvePendingIdentifierScopes;
|
|
|
|
+
|
|
|
|
+ ResolveSpecializedElements;
|
|
|
|
+
|
|
|
|
+ // check dangling references
|
|
Node:=FElementRefs.FindLowest;
|
|
Node:=FElementRefs.FindLowest;
|
|
while Node<>nil do
|
|
while Node<>nil do
|
|
begin
|
|
begin
|
|
@@ -6405,12 +6471,21 @@ var
|
|
ErrorEl: TPasElement;
|
|
ErrorEl: TPasElement;
|
|
PendSpec: TPCUReaderPendingSpecialized;
|
|
PendSpec: TPCUReaderPendingSpecialized;
|
|
PendParam: TPCUReaderPendingSpecializedParam;
|
|
PendParam: TPCUReaderPendingSpecializedParam;
|
|
|
|
+ SpecName: string;
|
|
begin
|
|
begin
|
|
ErrorEl:=GenEl;
|
|
ErrorEl:=GenEl;
|
|
if ParamIDs.Count=0 then
|
|
if ParamIDs.Count=0 then
|
|
RaiseMsg(20200222190934,ErrorEl);
|
|
RaiseMsg(20200222190934,ErrorEl);
|
|
- PendSpec:=AddPendingSpecialize(GenEl,ParamIDs.Count);
|
|
|
|
|
|
+ if not ReadInteger(Obj,'Id',Id,GenEl) then
|
|
|
|
+ RaiseMsg(20200531085133,GenEl);
|
|
|
|
+ if not ReadString(Obj,'SpecName',SpecName,GenEl) then
|
|
|
|
+ RaiseMsg(20200531085133,GenEl);
|
|
|
|
+
|
|
|
|
+ PendSpec:=AddPendingSpecialize(Id,SpecName);
|
|
PendSpec.Obj:=Obj;
|
|
PendSpec.Obj:=Obj;
|
|
|
|
+ PendSpec.GenericEl:=GenEl;
|
|
|
|
+
|
|
|
|
+ PendSpec.Params:=TFPList.Create;
|
|
for i:=0 to ParamIDs.Count-1 do
|
|
for i:=0 to ParamIDs.Count-1 do
|
|
begin
|
|
begin
|
|
if ParamIDs.Types[i]<>jtNumber then
|
|
if ParamIDs.Types[i]<>jtNumber then
|
|
@@ -6418,9 +6493,11 @@ begin
|
|
Id:=ParamIDs[i].AsInteger;
|
|
Id:=ParamIDs[i].AsInteger;
|
|
if Id<=0 then
|
|
if Id<=0 then
|
|
RaiseMsg(20200222191724,ErrorEl,IntToStr(i));
|
|
RaiseMsg(20200222191724,ErrorEl,IntToStr(i));
|
|
- PendParam:=TPCUReaderPendingSpecializedParam(PendSpec.Params[i]);
|
|
|
|
|
|
+ PendParam:=TPCUReaderPendingSpecializedParam.Create;
|
|
|
|
+ PendSpec.Params.Add(PendParam);
|
|
|
|
+ PendParam.Spec:=PendSpec;
|
|
|
|
+ PendParam.Index:=i;
|
|
PendParam.Id:=Id;
|
|
PendParam.Id:=Id;
|
|
- //PromiseSetElReference(Id,@Set_SpecializeParam,PendParam,ErrorEl);
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|