|
@@ -687,6 +687,7 @@ type
|
|
Step: TPSSpecializeStep;
|
|
Step: TPSSpecializeStep;
|
|
FirstSpecialize: TPasElement;
|
|
FirstSpecialize: TPasElement;
|
|
Params: TPasTypeArray;
|
|
Params: TPasTypeArray;
|
|
|
|
+ ImplProcs: TFPList;
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
property SpecializedType: TPasGenericType read FSpecializedType write SetSpecializedType;
|
|
property SpecializedType: TPasGenericType read FSpecializedType write SetSpecializedType;
|
|
end;
|
|
end;
|
|
@@ -1019,7 +1020,8 @@ type
|
|
end;
|
|
end;
|
|
|
|
|
|
TPasProcedureScopeFlag = (
|
|
TPasProcedureScopeFlag = (
|
|
- ppsfIsGroupOverload // mode objfpc: one overload is enough for all procs in same scope
|
|
|
|
|
|
+ ppsfIsGroupOverload, // mode objfpc: one overload is enough for all procs in same scope
|
|
|
|
+ ppsfIsSpecialized
|
|
);
|
|
);
|
|
TPasProcedureScopeFlags = set of TPasProcedureScopeFlag;
|
|
TPasProcedureScopeFlags = set of TPasProcedureScopeFlag;
|
|
|
|
|
|
@@ -1712,12 +1714,20 @@ type
|
|
function CreateSpecializedType(El: TPasSpecializeType;
|
|
function CreateSpecializedType(El: TPasSpecializeType;
|
|
const ParamsResolved: TPasTypeArray): TPSSpecializedItem; virtual;
|
|
const ParamsResolved: TPasTypeArray): TPSSpecializedItem; virtual;
|
|
function InitSpecializeScopes(El: TPasElement): integer; virtual;
|
|
function InitSpecializeScopes(El: TPasElement): integer; virtual;
|
|
- procedure SpecializeInterface(GenericType: TPasGenericType; SpecializedItem: TPSSpecializedItem); virtual;
|
|
|
|
|
|
+ procedure SpecializeGenTypeIntf(GenericType: TPasGenericType; SpecializedItem: TPSSpecializedItem); virtual;
|
|
|
|
+ procedure SpecializeGenTypeImpl(GenericType: TPasGenericType; SpecializedItem: TPSSpecializedItem); virtual;
|
|
procedure SpecializeMembers(GenMembersType, SpecMembersType: TPasMembersType); virtual;
|
|
procedure SpecializeMembers(GenMembersType, SpecMembersType: TPasMembersType); virtual;
|
|
procedure SpecializeElement(GenEl, SpecEl: TPasElement);
|
|
procedure SpecializeElement(GenEl, SpecEl: TPasElement);
|
|
procedure SpecializePasElementProperties(GenEl, SpecEl: TPasElement);
|
|
procedure SpecializePasElementProperties(GenEl, SpecEl: TPasElement);
|
|
procedure SpecializeVariable(GenEl, SpecEl: TPasVariable);
|
|
procedure SpecializeVariable(GenEl, SpecEl: TPasVariable);
|
|
procedure SpecializeElType(GenEl, SpecEl: TPasElement; GenElType: TPasType; var SpecElType: TPasType);
|
|
procedure SpecializeElType(GenEl, SpecEl: TPasElement; GenElType: TPasType; var SpecElType: TPasType);
|
|
|
|
+ procedure SpecializeElExpr(GenEl, SpecEl: TPasElement; GenElExpr: TPasExpr; var SpecElExpr: TPasExpr);
|
|
|
|
+ procedure SpecializeProcedure(GenEl, SpecEl: TPasProcedure);
|
|
|
|
+ procedure SpecializeProcedureType(GenEl, SpecEl: TPasProcedureType);
|
|
|
|
+ procedure SpecializeProcedureBody(GenEl, SpecEl: TProcedureBody);
|
|
|
|
+ procedure SpecializeDeclarations(GenEl, SpecEl: TPasDeclarations);
|
|
|
|
+ procedure SpecializeArgument(GenEl, SpecEl: TPasArgument);
|
|
|
|
+ procedure SpecializeImplBlock(GenEl, SpecEl: TPasImplBlock);
|
|
protected
|
|
protected
|
|
// custom types (added by descendant resolvers)
|
|
// custom types (added by descendant resolvers)
|
|
function CheckAssignCompatibilityCustom(
|
|
function CheckAssignCompatibilityCustom(
|
|
@@ -2898,7 +2908,16 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TPSSpecializedItem.Destroy;
|
|
destructor TPSSpecializedItem.Destroy;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
begin
|
|
begin
|
|
|
|
+ if ImplProcs<>nil then
|
|
|
|
+ begin
|
|
|
|
+ for i:=0 to ImplProcs.Count-1 do
|
|
|
|
+ TPasElement(ImplProcs[i]).Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
+ ImplProcs.Free;
|
|
|
|
+ ImplProcs:=nil;
|
|
|
|
+ end;
|
|
SpecializedType:=nil;
|
|
SpecializedType:=nil;
|
|
inherited Destroy;
|
|
inherited Destroy;
|
|
end;
|
|
end;
|
|
@@ -5451,7 +5470,8 @@ begin
|
|
C:=El.ClassType;
|
|
C:=El.ClassType;
|
|
if C=TPasClassType then
|
|
if C=TPasClassType then
|
|
begin
|
|
begin
|
|
- if TPasClassType(El).IsForward and (TPasClassType(El).CustomData=nil) then
|
|
|
|
|
|
+ if TPasClassType(El).IsForward
|
|
|
|
+ and not (TPasClassType(El).CustomData is TResolvedReference) then
|
|
RaiseMsg(20170216151534,nForwardTypeNotResolved,sForwardTypeNotResolved,[El.Name],El);
|
|
RaiseMsg(20170216151534,nForwardTypeNotResolved,sForwardTypeNotResolved,[El.Name],El);
|
|
end
|
|
end
|
|
else if (C=TPasClassOfType) then
|
|
else if (C=TPasClassOfType) then
|
|
@@ -5895,7 +5915,7 @@ begin
|
|
for j:=0 to FScopeCount-1 do
|
|
for j:=0 to FScopeCount-1 do
|
|
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
|
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
- SpecializeInterface(El,SpecializedItem);
|
|
|
|
|
|
+ SpecializeGenTypeIntf(El,SpecializedItem);
|
|
|
|
|
|
{$IFDEF VerbosePasResolver}
|
|
{$IFDEF VerbosePasResolver}
|
|
writeln('TPasResolver.FinishClassType Finished specialize interface: ',GetObjName(SpecializedItem.SpecializedType),' ',ScopeCount,' FStashScopeCount=',FStashScopeCount);
|
|
writeln('TPasResolver.FinishClassType Finished specialize interface: ',GetObjName(SpecializedItem.SpecializedType),' ',ScopeCount,' FStashScopeCount=',FStashScopeCount);
|
|
@@ -6296,12 +6316,12 @@ begin
|
|
if (Proc<>nil) and (Proc.ProcType=El) then
|
|
if (Proc<>nil) and (Proc.ProcType=El) then
|
|
begin
|
|
begin
|
|
// finished header of a procedure declaration
|
|
// finished header of a procedure declaration
|
|
- // -> search the best fitting proc
|
|
|
|
CheckTopScope(FScopeClass_Proc);
|
|
CheckTopScope(FScopeClass_Proc);
|
|
{$IFDEF VerbosePasResolver}
|
|
{$IFDEF VerbosePasResolver}
|
|
writeln('TPasResolver.FinishProcedureHeader El=',GetTreeDbg(El),' ',GetElementSourcePosStr(El),' IsForward=',Proc.IsForward,' Parent=',GetObjName(El.Parent));
|
|
writeln('TPasResolver.FinishProcedureHeader El=',GetTreeDbg(El),' ',GetElementSourcePosStr(El),' IsForward=',Proc.IsForward,' Parent=',GetObjName(El.Parent));
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
ProcName:=Proc.Name;
|
|
ProcName:=Proc.Name;
|
|
|
|
+ ProcScope:=Proc.CustomData as TPasProcedureScope;
|
|
|
|
|
|
if El is TPasFunctionType then
|
|
if El is TPasFunctionType then
|
|
CheckUseAsType(TPasFunctionType(El).ResultEl.ResultType,20190123095743,TPasFunctionType(El).ResultEl);
|
|
CheckUseAsType(TPasFunctionType(El).ResultEl.ResultType,20190123095743,TPasFunctionType(El).ResultEl);
|
|
@@ -6484,7 +6504,7 @@ begin
|
|
and not IsValidIdent(ProcName) then
|
|
and not IsValidIdent(ProcName) then
|
|
RaiseNotYetImplemented(20160922163407,El);
|
|
RaiseNotYetImplemented(20160922163407,El);
|
|
|
|
|
|
- if El is TPasFunctionType then
|
|
|
|
|
|
+ if (El is TPasFunctionType) and not (ppsfIsSpecialized in ProcScope.Flags) then
|
|
EmitTypeHints(TPasFunctionType(El).ResultEl,TPasFunctionType(El).ResultEl.ResultType);
|
|
EmitTypeHints(TPasFunctionType(El).ResultEl,TPasFunctionType(El).ResultEl.ResultType);
|
|
|
|
|
|
if Proc.PublicName<>nil then
|
|
if Proc.PublicName<>nil then
|
|
@@ -6519,49 +6539,50 @@ begin
|
|
// finish interface/implementation/nested procedure
|
|
// finish interface/implementation/nested procedure
|
|
if (ProcName<>'') and ProcNeedsBody(Proc) then
|
|
if (ProcName<>'') and ProcNeedsBody(Proc) then
|
|
begin
|
|
begin
|
|
- // check if there is a forward declaration
|
|
|
|
- //writeln('TPasResolver.FinishProcedureType ',GetObjName(TopScope),' ',GetObjName(Scopes[ScopeCount-2]));
|
|
|
|
- ParentScope:=GetParentLocalScope as TPasIdentifierScope;
|
|
|
|
- //writeln('TPasResolver.FinishProcedureType FindForward2 ParentScope=',GetObjName(ParentScope),'=',GetObjName(ParentScope.Element),' Proc=',GetObjName(Proc),' at ',GetElementSourcePosStr(Proc));
|
|
|
|
- DeclProc:=FindProcSameSignature(ProcName,Proc,ParentScope,true);
|
|
|
|
- //writeln('TPasResolver.FinishProcedureType FindForward3 DeclProc=',GetObjName(DeclProc),' Proc.Parent=',GetObjName(Proc.Parent));
|
|
|
|
- //if DeclProc<>nil then writeln('TPasResolver.FinishProcedureType DeclProc at ',GetElementSourcePosStr(DeclProc));
|
|
|
|
- if (DeclProc=nil) and (Proc.Parent.ClassType=TImplementationSection) then
|
|
|
|
- DeclProc:=FindProcSameSignature(ProcName,Proc,
|
|
|
|
- (Proc.GetModule.InterfaceSection.CustomData) as TPasIdentifierScope,true);
|
|
|
|
- //writeln('TPasResolver.FinishProcedureType FindForward4 ',GetObjName(DeclProc),' at ',GetElementSourcePosStr(DeclProc));
|
|
|
|
- if (DeclProc<>nil) then
|
|
|
|
- begin
|
|
|
|
- if ProcNeedsImplProc(DeclProc) then
|
|
|
|
|
|
+ if not (ppsfIsSpecialized in ProcScope.Flags) then
|
|
|
|
+ begin
|
|
|
|
+ // check if there is a forward declaration
|
|
|
|
+ //writeln('TPasResolver.FinishProcedureType ',GetObjName(TopScope),' ',GetObjName(Scopes[ScopeCount-2]));
|
|
|
|
+ ParentScope:=GetParentLocalScope as TPasIdentifierScope;
|
|
|
|
+ //writeln('TPasResolver.FinishProcedureType FindForward2 ParentScope=',GetObjName(ParentScope),'=',GetObjName(ParentScope.Element),' Proc=',GetObjName(Proc),' at ',GetElementSourcePosStr(Proc));
|
|
|
|
+ DeclProc:=FindProcSameSignature(ProcName,Proc,ParentScope,true);
|
|
|
|
+ //writeln('TPasResolver.FinishProcedureType FindForward3 DeclProc=',GetObjName(DeclProc),' Proc.Parent=',GetObjName(Proc.Parent));
|
|
|
|
+ //if DeclProc<>nil then writeln('TPasResolver.FinishProcedureType DeclProc at ',GetElementSourcePosStr(DeclProc));
|
|
|
|
+ if (DeclProc=nil) and (Proc.Parent.ClassType=TImplementationSection) then
|
|
|
|
+ DeclProc:=FindProcSameSignature(ProcName,Proc,
|
|
|
|
+ (Proc.GetModule.InterfaceSection.CustomData) as TPasIdentifierScope,true);
|
|
|
|
+ //writeln('TPasResolver.FinishProcedureType FindForward4 ',GetObjName(DeclProc),' at ',GetElementSourcePosStr(DeclProc));
|
|
|
|
+ if (DeclProc<>nil) then
|
|
begin
|
|
begin
|
|
- // found forward declaration
|
|
|
|
- DeclProcScope:=DeclProc.CustomData as TPasProcedureScope;
|
|
|
|
- if DeclProcScope.ImplProc<>nil then
|
|
|
|
- RaiseMsg(20180318222430,nDuplicateIdentifier,sDuplicateIdentifier,
|
|
|
|
- [DeclProcScope.ImplProc.Name,GetElementSourcePosStr(DeclProcScope.ImplProc)],Proc);
|
|
|
|
- // connect
|
|
|
|
- {$IFDEF VerbosePasResolver}
|
|
|
|
- writeln('TPasResolver.FinishProcedureHeader forward found: Proc2=',GetTreeDbg(DeclProc),' ',GetElementSourcePosStr(DeclProc),' IsForward=',DeclProc.IsForward,' Parent=',GetObjName(DeclProc.Parent));
|
|
|
|
- {$ENDIF}
|
|
|
|
- CheckProcSignatureMatch(DeclProc,Proc,true);
|
|
|
|
- DeclProcScope.ImplProc:=Proc;
|
|
|
|
- ProcScope:=Proc.CustomData as TPasProcedureScope;
|
|
|
|
- ProcScope.DeclarationProc:=DeclProc;
|
|
|
|
- // remove ImplProc from scope
|
|
|
|
- (ParentScope as TPasIdentifierScope).RemoveLocalIdentifier(Proc);
|
|
|
|
- // replace arguments with declaration arguments
|
|
|
|
- ReplaceProcScopeImplArgsWithDeclArgs(ProcScope);
|
|
|
|
- exit;
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- RaiseMsg(20180318220543,nDuplicateIdentifier,sDuplicateIdentifier,
|
|
|
|
- [DeclProc.Name,GetElementSourcePosStr(DeclProc)],Proc);
|
|
|
|
|
|
+ if ProcNeedsImplProc(DeclProc) then
|
|
|
|
+ begin
|
|
|
|
+ // found forward declaration
|
|
|
|
+ DeclProcScope:=DeclProc.CustomData as TPasProcedureScope;
|
|
|
|
+ if DeclProcScope.ImplProc<>nil then
|
|
|
|
+ RaiseMsg(20180318222430,nDuplicateIdentifier,sDuplicateIdentifier,
|
|
|
|
+ [DeclProcScope.ImplProc.Name,GetElementSourcePosStr(DeclProcScope.ImplProc)],Proc);
|
|
|
|
+ // connect
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPasResolver.FinishProcedureHeader forward found: Proc2=',GetTreeDbg(DeclProc),' ',GetElementSourcePosStr(DeclProc),' IsForward=',DeclProc.IsForward,' Parent=',GetObjName(DeclProc.Parent));
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ CheckProcSignatureMatch(DeclProc,Proc,true);
|
|
|
|
+ DeclProcScope.ImplProc:=Proc;
|
|
|
|
+ ProcScope.DeclarationProc:=DeclProc;
|
|
|
|
+ // remove ImplProc from scope
|
|
|
|
+ (ParentScope as TPasIdentifierScope).RemoveLocalIdentifier(Proc);
|
|
|
|
+ // replace arguments with declaration arguments
|
|
|
|
+ ReplaceProcScopeImplArgsWithDeclArgs(ProcScope);
|
|
|
|
+ exit;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ RaiseMsg(20180318220543,nDuplicateIdentifier,sDuplicateIdentifier,
|
|
|
|
+ [DeclProc.Name,GetElementSourcePosStr(DeclProc)],Proc);
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
// forward declaration
|
|
// forward declaration
|
|
- ProcScope:=Proc.CustomData as TPasProcedureScope;
|
|
|
|
// ToDo: store the scanner flags *before* it has parsed the token after the proc
|
|
// ToDo: store the scanner flags *before* it has parsed the token after the proc
|
|
StoreScannerFlagsInProc(ProcScope);
|
|
StoreScannerFlagsInProc(ProcScope);
|
|
end;
|
|
end;
|
|
@@ -6727,22 +6748,8 @@ begin
|
|
RaiseMsg(20170216151717,nInvalidXModifierY,sInvalidXModifierY,[GetElementTypeName(ImplProc),'export'],ImplProc);
|
|
RaiseMsg(20170216151717,nInvalidXModifierY,sInvalidXModifierY,[GetElementTypeName(ImplProc),'export'],ImplProc);
|
|
|
|
|
|
ProcName:=ImplProc.Name;
|
|
ProcName:=ImplProc.Name;
|
|
- {$IFDEF VerbosePasResolver}
|
|
|
|
- writeln('TPasResolver.FinishMethodBodyHeader searching declaration "',ProcName,'" ...');
|
|
|
|
- {$ENDIF}
|
|
|
|
-
|
|
|
|
- repeat
|
|
|
|
- p:=Pos('.',ProcName);
|
|
|
|
- if p<1 then break;
|
|
|
|
- Delete(ProcName,1,p);
|
|
|
|
- until false;
|
|
|
|
-
|
|
|
|
- // search ImplProc in class
|
|
|
|
- if not IsValidIdent(ProcName) then
|
|
|
|
- RaiseNotYetImplemented(20160922163421,ImplProc.ProcType);
|
|
|
|
-
|
|
|
|
- // search proc in class/record
|
|
|
|
ImplProcScope:=ImplProc.CustomData as TPasProcedureScope;
|
|
ImplProcScope:=ImplProc.CustomData as TPasProcedureScope;
|
|
|
|
+
|
|
ClassOrRecScope:=ImplProcScope.ClassRecScope;
|
|
ClassOrRecScope:=ImplProcScope.ClassRecScope;
|
|
if ClassOrRecScope=nil then
|
|
if ClassOrRecScope=nil then
|
|
RaiseInternalError(20161013172346);
|
|
RaiseInternalError(20161013172346);
|
|
@@ -6750,32 +6757,61 @@ begin
|
|
if ImplProcScope.GroupScope=nil then
|
|
if ImplProcScope.GroupScope=nil then
|
|
RaiseInternalError(20190120135017);
|
|
RaiseInternalError(20190120135017);
|
|
|
|
|
|
- if ImplProc.ClassType=TPasClassConstructor then
|
|
|
|
- DeclProc:=ClassOrRecScope.ClassConstructor
|
|
|
|
- else if ImplProc.ClassType=TPasClassDestructor then
|
|
|
|
- DeclProc:=ClassOrRecScope.ClassDestructor
|
|
|
|
|
|
+ repeat
|
|
|
|
+ p:=Pos('.',ProcName);
|
|
|
|
+ if p<1 then break;
|
|
|
|
+ Delete(ProcName,1,p);
|
|
|
|
+ until false;
|
|
|
|
+
|
|
|
|
+ if ImplProcScope.DeclarationProc=nil then
|
|
|
|
+ begin
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPasResolver.FinishMethodImplHeader searching declaration "',ImplProc.Name,'" ...');
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ // search ImplProc in class
|
|
|
|
+ if not IsValidIdent(ProcName) then
|
|
|
|
+ RaiseNotYetImplemented(20160922163421,ImplProc.ProcType);
|
|
|
|
+
|
|
|
|
+ // search proc in class/record
|
|
|
|
+ if ImplProc.ClassType=TPasClassConstructor then
|
|
|
|
+ DeclProc:=ClassOrRecScope.ClassConstructor
|
|
|
|
+ else if ImplProc.ClassType=TPasClassDestructor then
|
|
|
|
+ DeclProc:=ClassOrRecScope.ClassDestructor
|
|
|
|
+ else
|
|
|
|
+ DeclProc:=FindProcSameSignature(ProcName,ImplProc,ClassOrRecScope,false);
|
|
|
|
+ if DeclProc=nil then
|
|
|
|
+ RaiseIdentifierNotFound(20170216151720,ImplProc.Name,ImplProc.ProcType);
|
|
|
|
+ DeclProcScope:=DeclProc.CustomData as TPasProcedureScope;
|
|
|
|
+ ImplProc.ProcType.IsOfObject:=DeclProc.ProcType.IsOfObject;
|
|
|
|
+
|
|
|
|
+ // connect method declaration and body
|
|
|
|
+ if DeclProcScope.ImplProc<>nil then
|
|
|
|
+ RaiseMsg(20180212094546,nDuplicateIdentifier,sDuplicateIdentifier,
|
|
|
|
+ [DeclProcScope.ImplProc.Name,GetElementSourcePosStr(DeclProcScope.ImplProc)],
|
|
|
|
+ ImplProc);
|
|
|
|
+ if DeclProc.IsAbstract then
|
|
|
|
+ RaiseMsg(20170216151722,nAbstractMethodsMustNotHaveImplementation,sAbstractMethodsMustNotHaveImplementation,[],ImplProc);
|
|
|
|
+ if DeclProc.IsExternal then
|
|
|
|
+ RaiseXExpectedButYFound(20170216151725,'method','external method',ImplProc);
|
|
|
|
+ CheckProcSignatureMatch(DeclProc,ImplProc,true);
|
|
|
|
+ ImplProcScope.DeclarationProc:=DeclProc;
|
|
|
|
+ DeclProcScope.ImplProc:=ImplProc;
|
|
|
|
+
|
|
|
|
+ // replace arguments in scope with declaration arguments
|
|
|
|
+ ReplaceProcScopeImplArgsWithDeclArgs(ImplProcScope);
|
|
|
|
+ end
|
|
|
|
+ else if ppsfIsSpecialized in ImplProcScope.Flags then
|
|
|
|
+ begin
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPasResolver.FinishMethodImplHeader specialized "',ImplProc.Name,'" ...');
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ DeclProc:=ImplProcScope.DeclarationProc;
|
|
|
|
+ DeclProcScope:=DeclProc.CustomData as TPasProcedureScope;
|
|
|
|
+ if DeclProcScope.ImplProc<>ImplProc then
|
|
|
|
+ RaiseNotYetImplemented(20190804182220,ImplProc);
|
|
|
|
+ end
|
|
else
|
|
else
|
|
- DeclProc:=FindProcSameSignature(ProcName,ImplProc,ClassOrRecScope,false);
|
|
|
|
- if DeclProc=nil then
|
|
|
|
- RaiseIdentifierNotFound(20170216151720,ImplProc.Name,ImplProc.ProcType);
|
|
|
|
- DeclProcScope:=DeclProc.CustomData as TPasProcedureScope;
|
|
|
|
- ImplProc.ProcType.IsOfObject:=DeclProc.ProcType.IsOfObject;
|
|
|
|
-
|
|
|
|
- // connect method declaration and body
|
|
|
|
- if DeclProcScope.ImplProc<>nil then
|
|
|
|
- RaiseMsg(20180212094546,nDuplicateIdentifier,sDuplicateIdentifier,
|
|
|
|
- [DeclProcScope.ImplProc.Name,GetElementSourcePosStr(DeclProcScope.ImplProc)],
|
|
|
|
- ImplProc);
|
|
|
|
- if DeclProc.IsAbstract then
|
|
|
|
- RaiseMsg(20170216151722,nAbstractMethodsMustNotHaveImplementation,sAbstractMethodsMustNotHaveImplementation,[],ImplProc);
|
|
|
|
- if DeclProc.IsExternal then
|
|
|
|
- RaiseXExpectedButYFound(20170216151725,'method','external method',ImplProc);
|
|
|
|
- CheckProcSignatureMatch(DeclProc,ImplProc,true);
|
|
|
|
- ImplProcScope.DeclarationProc:=DeclProc;
|
|
|
|
- DeclProcScope.ImplProc:=ImplProc;
|
|
|
|
-
|
|
|
|
- // replace arguments in scope with declaration arguments
|
|
|
|
- ReplaceProcScopeImplArgsWithDeclArgs(ImplProcScope);
|
|
|
|
|
|
+ RaiseNotYetImplemented(20190804181222,ImplProc);
|
|
|
|
|
|
if not DeclProc.IsStatic then
|
|
if not DeclProc.IsStatic then
|
|
begin
|
|
begin
|
|
@@ -6828,7 +6864,7 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
{$IFDEF VerbosePasResolver}
|
|
{$IFDEF VerbosePasResolver}
|
|
- writeln('TPasResolver.FinishMethodBodyHeader END of searching proc "',ImplProc.Name,'" ...');
|
|
|
|
|
|
+ writeln('TPasResolver.FinishMethodBodyHeader END "',ImplProc.Name,'" ...');
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -10725,6 +10761,8 @@ var
|
|
DeclEl: TPasElement;
|
|
DeclEl: TPasElement;
|
|
Proc: TPasProcedure;
|
|
Proc: TPasProcedure;
|
|
aClassOrRec: TPasMembersType;
|
|
aClassOrRec: TPasMembersType;
|
|
|
|
+ ClassOrRecScope: TPasClassOrRecordScope;
|
|
|
|
+ SpecializedTypes: TObjectList;
|
|
begin
|
|
begin
|
|
if IsElementSkipped(El) then exit;
|
|
if IsElementSkipped(El) then exit;
|
|
if El is TPasDeclarations then
|
|
if El is TPasDeclarations then
|
|
@@ -10745,9 +10783,19 @@ begin
|
|
else if El is TPasMembersType then
|
|
else if El is TPasMembersType then
|
|
begin
|
|
begin
|
|
aClassOrRec:=TPasMembersType(El);
|
|
aClassOrRec:=TPasMembersType(El);
|
|
- if (aClassOrRec is TPasClassType)
|
|
|
|
- and (TPasClassType(aClassOrRec).ObjKind in [okInterface,okDispInterface])
|
|
|
|
- then exit;
|
|
|
|
|
|
+ if (aClassOrRec is TPasClassType) then
|
|
|
|
+ begin
|
|
|
|
+ if (TPasClassType(aClassOrRec).ObjKind in [okInterface,okDispInterface]) then
|
|
|
|
+ exit;
|
|
|
|
+ if TPasClassType(aClassOrRec).IsForward then
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ ClassOrRecScope:=aClassOrRec.CustomData as TPasClassOrRecordScope;
|
|
|
|
+ if ClassOrRecScope.SpecializedFrom<>nil then
|
|
|
|
+ exit;
|
|
|
|
+ // finish implementation of (generic) class/record
|
|
|
|
+ if ClassOrRecScope.GenericStep<>psgsInterfaceParsed then
|
|
|
|
+ RaiseNotYetImplemented(20190804115324,El);
|
|
for i:=0 to aClassOrRec.Members.Count-1 do
|
|
for i:=0 to aClassOrRec.Members.Count-1 do
|
|
begin
|
|
begin
|
|
DeclEl:=TPasElement(aClassOrRec.Members[i]);
|
|
DeclEl:=TPasElement(aClassOrRec.Members[i]);
|
|
@@ -10760,6 +10808,13 @@ begin
|
|
[GetElementTypeName(Proc),Proc.Name],Proc);
|
|
[GetElementTypeName(Proc),Proc.Name],Proc);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
+ ClassOrRecScope.GenericStep:=psgsImplementationParsed;
|
|
|
|
+
|
|
|
|
+ // finish specializations
|
|
|
|
+ SpecializedTypes:=ClassOrRecScope.SpecializedTypes;
|
|
|
|
+ if SpecializedTypes<>nil then
|
|
|
|
+ for i:=0 to SpecializedTypes.Count-1 do
|
|
|
|
+ SpecializeGenTypeImpl(aClassOrRec,TPSSpecializedItem(SpecializedTypes[i]));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -10820,6 +10875,10 @@ begin
|
|
FinishSection(TPasSectionScope(TopScope).Element as TPasSection);
|
|
FinishSection(TPasSectionScope(TopScope).Element as TPasSection);
|
|
if TopScope is TPasModuleScope then
|
|
if TopScope is TPasModuleScope then
|
|
TPasModuleScope(TopScope).BoolSwitches:=CurrentParser.Scanner.CurrentBoolSwitches;
|
|
TPasModuleScope(TopScope).BoolSwitches:=CurrentParser.Scanner.CurrentBoolSwitches;
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ if FPendingForwardProcs.IndexOf(El)=0 then
|
|
|
|
+ RaiseNotYetImplemented(20190804114718,El);
|
|
|
|
+ {$ENDIF}
|
|
FPendingForwardProcs.Add(El); // check forward declarations at the end
|
|
FPendingForwardProcs.Add(El); // check forward declarations at the end
|
|
Scope:=TPasSectionScope(PushScope(El,ScopeClass_Section));
|
|
Scope:=TPasSectionScope(PushScope(El,ScopeClass_Section));
|
|
Scope.BoolSwitches:=CurrentParser.Scanner.CurrentBoolSwitches;
|
|
Scope.BoolSwitches:=CurrentParser.Scanner.CurrentBoolSwitches;
|
|
@@ -10853,6 +10912,10 @@ begin
|
|
RaiseInvalidScopeForElement(20160922163508,El);
|
|
RaiseInvalidScopeForElement(20160922163508,El);
|
|
if El.Name<>'' then begin
|
|
if El.Name<>'' then begin
|
|
AddIdentifier(TPasIdentifierScope(TopScope),El.Name,El,pikSimple);
|
|
AddIdentifier(TPasIdentifierScope(TopScope),El.Name,El,pikSimple);
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ if FPendingForwardProcs.IndexOf(El)=0 then
|
|
|
|
+ RaiseNotYetImplemented(20190804114737,El);
|
|
|
|
+ {$ENDIF}
|
|
FPendingForwardProcs.Add(El); // check forward declarations at the end
|
|
FPendingForwardProcs.Add(El); // check forward declarations at the end
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -10931,6 +10994,10 @@ begin
|
|
else
|
|
else
|
|
AddIdentifier(CurScope,El.Name,El,pikSimple);
|
|
AddIdentifier(CurScope,El.Name,El,pikSimple);
|
|
|
|
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ if FPendingForwardProcs.IndexOf(El)>=0 then
|
|
|
|
+ RaiseNotYetImplemented(20190804114746,El);
|
|
|
|
+ {$ENDIF}
|
|
FPendingForwardProcs.Add(El); // check forward declarations at the end
|
|
FPendingForwardProcs.Add(El); // check forward declarations at the end
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -11109,107 +11176,129 @@ begin
|
|
// Note: El.ProcType is nil ! It is parsed later.
|
|
// Note: El.ProcType is nil ! It is parsed later.
|
|
|
|
|
|
HasDot:=Pos('.',ProcName)>1;
|
|
HasDot:=Pos('.',ProcName)>1;
|
|
- IsClassConDestructor:=(El.ClassType=TPasClassConstructor)
|
|
|
|
- or (El.ClassType=TPasClassDestructor);
|
|
|
|
- if (not HasDot) and IsClassConDestructor then
|
|
|
|
- begin
|
|
|
|
- if ProcName='' then
|
|
|
|
- RaiseNotYetImplemented(20181231145302,El);
|
|
|
|
- if not (LocalScope is TPasClassOrRecordScope) then
|
|
|
|
- RaiseInvalidScopeForElement(20181231143831,El);
|
|
|
|
- ClassOrRecScope:=TPasClassOrRecordScope(LocalScope);
|
|
|
|
- if El.ClassType=TPasClassConstructor then
|
|
|
|
- AddClassConDestructor(ClassOrRecScope,TPasProcedure(ClassOrRecScope.ClassConstructor))
|
|
|
|
- else
|
|
|
|
- AddClassConDestructor(ClassOrRecScope,TPasProcedure(ClassOrRecScope.ClassDestructor));
|
|
|
|
- end;
|
|
|
|
|
|
+ if El.CustomData is TPasProcedureScope then
|
|
|
|
+ begin
|
|
|
|
+ // adding a specialized implementation proc
|
|
|
|
+ ProcScope:=TPasProcedureScope(El.CustomData);
|
|
|
|
+ ClassOrRecScope:=ProcScope.ClassRecScope;
|
|
|
|
+ if ClassOrRecScope=nil then
|
|
|
|
+ RaiseNotYetImplemented(20190804175307,El);
|
|
|
|
+ ClassOrRecType:=TPasMembersType(ClassOrRecScope.Element);
|
|
|
|
+ if GetTypeParameterCount(ClassOrRecType)>0 then
|
|
|
|
+ RaiseNotYetImplemented(20190804175518,El);
|
|
|
|
+ if ProcScope.GroupScope<>nil then
|
|
|
|
+ RaiseNotYetImplemented(20190804175451,El);
|
|
|
|
|
|
- if (not HasDot) and (ProcName<>'')
|
|
|
|
- and not IsClassConDestructor // the name of a class con/destructor is irrelevant
|
|
|
|
- then
|
|
|
|
|
|
+ PushScope(ProcScope);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
begin
|
|
begin
|
|
- // add proc name to scope
|
|
|
|
- AddIdentifier(TPasIdentifierScope(CurScope),ProcName,El,pikProc);
|
|
|
|
- end;
|
|
|
|
|
|
+ IsClassConDestructor:=(El.ClassType=TPasClassConstructor)
|
|
|
|
+ or (El.ClassType=TPasClassDestructor);
|
|
|
|
+ if (not HasDot) and IsClassConDestructor then
|
|
|
|
+ begin
|
|
|
|
+ if ProcName='' then
|
|
|
|
+ RaiseNotYetImplemented(20181231145302,El);
|
|
|
|
+ if not (LocalScope is TPasClassOrRecordScope) then
|
|
|
|
+ RaiseInvalidScopeForElement(20181231143831,El);
|
|
|
|
+ ClassOrRecScope:=TPasClassOrRecordScope(LocalScope);
|
|
|
|
+ if El.ClassType=TPasClassConstructor then
|
|
|
|
+ AddClassConDestructor(ClassOrRecScope,TPasProcedure(ClassOrRecScope.ClassConstructor))
|
|
|
|
+ else
|
|
|
|
+ AddClassConDestructor(ClassOrRecScope,TPasProcedure(ClassOrRecScope.ClassDestructor));
|
|
|
|
+ end;
|
|
|
|
|
|
- ProcScope:=TPasProcedureScope(PushScope(El,FScopeClass_Proc));
|
|
|
|
- ProcScope.ModeSwitches:=CurrentParser.CurrentModeswitches;
|
|
|
|
- if HasDot then
|
|
|
|
- begin
|
|
|
|
- // method implementation -> search class
|
|
|
|
- {$IFDEF VerbosePasResolver}
|
|
|
|
- writeln('TPasResolver.AddProcedure searching class of "',ProcName,'" ...');
|
|
|
|
- {$ENDIF}
|
|
|
|
- ClassOrRecType:=nil;
|
|
|
|
- repeat
|
|
|
|
- p:=Pos('.',ProcName);
|
|
|
|
- if p<1 then
|
|
|
|
- begin
|
|
|
|
- if ClassOrRecType=nil then
|
|
|
|
- RaiseInternalError(20161013170829);
|
|
|
|
- break;
|
|
|
|
- end;
|
|
|
|
- aClassName:=LeftStr(ProcName,p-1);
|
|
|
|
- Delete(ProcName,1,p);
|
|
|
|
|
|
+ if (not HasDot) and (ProcName<>'')
|
|
|
|
+ and not IsClassConDestructor // the name of a class con/destructor is irrelevant and cannot be referenced
|
|
|
|
+ then
|
|
|
|
+ begin
|
|
|
|
+ // add proc name to scope
|
|
|
|
+ AddIdentifier(TPasIdentifierScope(CurScope),ProcName,El,pikProc);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ ProcScope:=TPasProcedureScope(PushScope(El,FScopeClass_Proc));
|
|
|
|
+ ProcScope.ModeSwitches:=CurrentParser.CurrentModeswitches;
|
|
|
|
+ if HasDot then
|
|
|
|
+ begin
|
|
|
|
+ // method implementation -> search class
|
|
{$IFDEF VerbosePasResolver}
|
|
{$IFDEF VerbosePasResolver}
|
|
- writeln('TPasResolver.AddProcedure searching class "',aClassName,'" ProcName="',ProcName,'" ...');
|
|
|
|
|
|
+ writeln('TPasResolver.AddProcedure searching class of "',ProcName,'" ...');
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
- if not IsValidIdent(aClassName) then
|
|
|
|
- RaiseNotYetImplemented(20161013170844,El);
|
|
|
|
|
|
+ ClassOrRecType:=nil;
|
|
|
|
+ repeat
|
|
|
|
+ p:=Pos('.',ProcName);
|
|
|
|
+ if p<1 then
|
|
|
|
+ begin
|
|
|
|
+ if ClassOrRecType=nil then
|
|
|
|
+ RaiseInternalError(20161013170829);
|
|
|
|
+ break;
|
|
|
|
+ end;
|
|
|
|
+ aClassName:=LeftStr(ProcName,p-1);
|
|
|
|
+ Delete(ProcName,1,p);
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPasResolver.AddProcedure searching class "',aClassName,'" ProcName="',ProcName,'" ...');
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ if not IsValidIdent(aClassName) then
|
|
|
|
+ RaiseNotYetImplemented(20161013170844,El);
|
|
|
|
|
|
- if ClassOrRecType<>nil then
|
|
|
|
- begin
|
|
|
|
- ClassOrRecScope:=TPasClassOrRecordScope(ClassOrRecType.CustomData);
|
|
|
|
- Identifier:=ClassOrRecScope.FindLocalIdentifier(aClassName);
|
|
|
|
- if Identifier=nil then
|
|
|
|
- RaiseIdentifierNotFound(20180430130635,aClassName,El)
|
|
|
|
|
|
+ if ClassOrRecType<>nil then
|
|
|
|
+ begin
|
|
|
|
+ ClassOrRecScope:=TPasClassOrRecordScope(ClassOrRecType.CustomData);
|
|
|
|
+ Identifier:=ClassOrRecScope.FindLocalIdentifier(aClassName);
|
|
|
|
+ if Identifier=nil then
|
|
|
|
+ RaiseIdentifierNotFound(20180430130635,aClassName,El)
|
|
|
|
+ else
|
|
|
|
+ CurEl:=Identifier.Element;
|
|
|
|
+ end
|
|
else
|
|
else
|
|
- CurEl:=Identifier.Element;
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- CurEl:=FindElementWithoutParams(aClassName,El,false);
|
|
|
|
|
|
+ CurEl:=FindElementWithoutParams(aClassName,El,false);
|
|
|
|
|
|
- if not (CurEl is TPasMembersType) then
|
|
|
|
- begin
|
|
|
|
- aClassName:=LeftStr(El.Name,length(El.Name)-length(ProcName)-1);
|
|
|
|
- {$IFDEF VerbosePasResolver}
|
|
|
|
- writeln('TPasResolver.AddProcedure searching class "',aClassName,'" ProcName="',ProcName,'" found: '+GetObjName(CurEl));
|
|
|
|
- {$ENDIF}
|
|
|
|
- RaiseXExpectedButYFound(20170216152557,
|
|
|
|
- 'class',aClassname+':'+GetElementTypeName(CurEl),El);
|
|
|
|
- end;
|
|
|
|
- ClassOrRecType:=TPasMembersType(CurEl);
|
|
|
|
- if ClassOrRecType is TPasClassType then
|
|
|
|
- begin
|
|
|
|
- if not (TPasClassType(ClassOrRecType).ObjKind in
|
|
|
|
- ([okClass]+okAllHelpers)) then
|
|
|
|
|
|
+ if not (CurEl is TPasMembersType) then
|
|
begin
|
|
begin
|
|
aClassName:=LeftStr(El.Name,length(El.Name)-length(ProcName)-1);
|
|
aClassName:=LeftStr(El.Name,length(El.Name)-length(ProcName)-1);
|
|
- RaiseXExpectedButYFound(20180321161722,
|
|
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPasResolver.AddProcedure searching class "',aClassName,'" ProcName="',ProcName,'" found: '+GetObjName(CurEl));
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ RaiseXExpectedButYFound(20170216152557,
|
|
'class',aClassname+':'+GetElementTypeName(CurEl),El);
|
|
'class',aClassname+':'+GetElementTypeName(CurEl),El);
|
|
- end
|
|
|
|
- end;
|
|
|
|
- if ClassOrRecType.GetModule<>El.GetModule then
|
|
|
|
- begin
|
|
|
|
- aClassName:=LeftStr(El.Name,length(El.Name)-length(ProcName)-1);
|
|
|
|
- RaiseMsg(20180211230432,nMethodClassXInOtherUnitY,sMethodClassXInOtherUnitY,
|
|
|
|
- [aClassName,ClassOrRecType.GetModule.Name],El);
|
|
|
|
- end;
|
|
|
|
- until false;
|
|
|
|
|
|
+ end;
|
|
|
|
+ ClassOrRecType:=TPasMembersType(CurEl);
|
|
|
|
+ if ClassOrRecType is TPasClassType then
|
|
|
|
+ begin
|
|
|
|
+ if not (TPasClassType(ClassOrRecType).ObjKind in
|
|
|
|
+ ([okClass]+okAllHelpers)) then
|
|
|
|
+ begin
|
|
|
|
+ aClassName:=LeftStr(El.Name,length(El.Name)-length(ProcName)-1);
|
|
|
|
+ RaiseXExpectedButYFound(20180321161722,
|
|
|
|
+ 'class',aClassname+':'+GetElementTypeName(CurEl),El);
|
|
|
|
+ end
|
|
|
|
+ end;
|
|
|
|
+ if ClassOrRecType.GetModule<>El.GetModule then
|
|
|
|
+ begin
|
|
|
|
+ aClassName:=LeftStr(El.Name,length(El.Name)-length(ProcName)-1);
|
|
|
|
+ RaiseMsg(20180211230432,nMethodClassXInOtherUnitY,sMethodClassXInOtherUnitY,
|
|
|
|
+ [aClassName,ClassOrRecType.GetModule.Name],El);
|
|
|
|
+ end;
|
|
|
|
+ until false;
|
|
|
|
|
|
- if not IsValidIdent(ProcName) then
|
|
|
|
- RaiseNotYetImplemented(20161013170956,El);
|
|
|
|
|
|
+ if not IsValidIdent(ProcName) then
|
|
|
|
+ RaiseNotYetImplemented(20161013170956,El);
|
|
|
|
|
|
- ProcScope.VisibilityContext:=ClassOrRecType;
|
|
|
|
- ProcScope.ClassRecScope:=NoNil(ClassOrRecType.CustomData) as TPasClassOrRecordScope;
|
|
|
|
|
|
+ ProcScope.VisibilityContext:=ClassOrRecType;
|
|
|
|
+ ProcScope.ClassRecScope:=NoNil(ClassOrRecType.CustomData) as TPasClassOrRecordScope;
|
|
|
|
+ end; // HasDot=true
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if HasDot then
|
|
|
|
+ begin
|
|
|
|
+ // create GroupScope
|
|
ProcScope.GroupScope:=CreateGroupScope(ClassOrRecType);
|
|
ProcScope.GroupScope:=CreateGroupScope(ClassOrRecType);
|
|
while ClassOrRecType.Parent is TPasMembersType do
|
|
while ClassOrRecType.Parent is TPasMembersType do
|
|
begin
|
|
begin
|
|
ClassOrRecType:=TPasMembersType(ClassOrRecType.Parent);
|
|
ClassOrRecType:=TPasMembersType(ClassOrRecType.Parent);
|
|
GroupScope_AddTypeAndAncestors(ProcScope.GroupScope,ClassOrRecType);
|
|
GroupScope_AddTypeAndAncestors(ProcScope.GroupScope,ClassOrRecType);
|
|
end;
|
|
end;
|
|
-
|
|
|
|
- end;// HasDot=true
|
|
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TPasResolver.AddArgument(El: TPasArgument);
|
|
procedure TPasResolver.AddArgument(El: TPasArgument);
|
|
@@ -14198,7 +14287,7 @@ function TPasResolver.CheckSpecializeConstraints(El: TPasSpecializeType
|
|
var
|
|
var
|
|
Params, GenericTemplateList: TFPList;
|
|
Params, GenericTemplateList: TFPList;
|
|
i, j: Integer;
|
|
i, j: Integer;
|
|
- P: TPasElement;
|
|
|
|
|
|
+ P, ParentEl: TPasElement;
|
|
ParamType, DestType: TPasType;
|
|
ParamType, DestType: TPasType;
|
|
ResolvedEl, ResolvedConstraint: TPasResolverResult;
|
|
ResolvedEl, ResolvedConstraint: TPasResolverResult;
|
|
GenTempl: TPasGenericTemplateType;
|
|
GenTempl: TPasGenericTemplateType;
|
|
@@ -14294,6 +14383,19 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
+
|
|
|
|
+ if Result then
|
|
|
|
+ begin
|
|
|
|
+ // check ParentEl types are specialized
|
|
|
|
+ ParentEl:=DestType.Parent;
|
|
|
|
+ while ParentEl<>nil do
|
|
|
|
+ begin
|
|
|
|
+ if (ParentEl is TPasGenericType)
|
|
|
|
+ and (GetTypeParameterCount(TPasGenericType(ParentEl))>0) then
|
|
|
|
+ exit(false); // parent is not specialized
|
|
|
|
+ ParentEl:=ParentEl.Parent;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TPasResolver.CreateSpecializedType(El: TPasSpecializeType;
|
|
function TPasResolver.CreateSpecializedType(El: TPasSpecializeType;
|
|
@@ -14357,7 +14459,7 @@ begin
|
|
NewEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF}; // fix refcount
|
|
NewEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF}; // fix refcount
|
|
|
|
|
|
if GenScope.GenericStep>=psgsInterfaceParsed then
|
|
if GenScope.GenericStep>=psgsInterfaceParsed then
|
|
- SpecializeInterface(GenericType,Result);
|
|
|
|
|
|
+ SpecializeGenTypeIntf(GenericType,Result);
|
|
|
|
|
|
{$IFDEF VerbosePasResolver}
|
|
{$IFDEF VerbosePasResolver}
|
|
writeln('TPasResolver.CreateSpecializedType FinishTypeDef:');
|
|
writeln('TPasResolver.CreateSpecializedType FinishTypeDef:');
|
|
@@ -14371,6 +14473,9 @@ begin
|
|
for i:=0 to FScopeCount-1 do
|
|
for i:=0 to FScopeCount-1 do
|
|
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
|
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
+
|
|
|
|
+ if GenScope.GenericStep>=psgsImplementationParsed then
|
|
|
|
+ SpecializeGenTypeImpl(GenericType,Result);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TPasResolver.InitSpecializeScopes(El: TPasElement): integer;
|
|
function TPasResolver.InitSpecializeScopes(El: TPasElement): integer;
|
|
@@ -14423,7 +14528,7 @@ begin
|
|
PushParentScopes(El.Parent);
|
|
PushParentScopes(El.Parent);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TPasResolver.SpecializeInterface(GenericType: TPasGenericType;
|
|
|
|
|
|
+procedure TPasResolver.SpecializeGenTypeIntf(GenericType: TPasGenericType;
|
|
SpecializedItem: TPSSpecializedItem);
|
|
SpecializedItem: TPSSpecializedItem);
|
|
var
|
|
var
|
|
GenericTemplateTypes: TFPList;
|
|
GenericTemplateTypes: TFPList;
|
|
@@ -14434,7 +14539,7 @@ var
|
|
HeaderScope: TPasClassHeaderScope;
|
|
HeaderScope: TPasClassHeaderScope;
|
|
begin
|
|
begin
|
|
if SpecializedItem.Step<>psssNone then
|
|
if SpecializedItem.Step<>psssNone then
|
|
- RaiseNotYetImplemented(20190801224849,GenericType,GetObjName(SpecializedItem.SpecializedType));
|
|
|
|
|
|
+ exit;
|
|
SpecializedItem.Step:=psssInterfaceBuilding;
|
|
SpecializedItem.Step:=psssInterfaceBuilding;
|
|
GenericTemplateTypes:=GenericType.GenericTemplateTypes;
|
|
GenericTemplateTypes:=GenericType.GenericTemplateTypes;
|
|
SpecType:=SpecializedItem.SpecializedType;
|
|
SpecType:=SpecializedItem.SpecializedType;
|
|
@@ -14463,7 +14568,8 @@ begin
|
|
RaiseNotYetImplemented(20190730182858,GenClassType);
|
|
RaiseNotYetImplemented(20190730182858,GenClassType);
|
|
NewClassType.IsExternal:=GenClassType.IsExternal;
|
|
NewClassType.IsExternal:=GenClassType.IsExternal;
|
|
NewClassType.IsShortDefinition:=GenClassType.IsShortDefinition;
|
|
NewClassType.IsShortDefinition:=GenClassType.IsShortDefinition;
|
|
- // ToDo GUIDExpr
|
|
|
|
|
|
+ if GenClassType.GUIDExpr<>nil then
|
|
|
|
+ SpecializeElExpr(GenClassType,NewClassType,GenClassType.GUIDExpr,NewClassType.GUIDExpr);
|
|
NewClassType.Modifiers.Assign(GenClassType.Modifiers);
|
|
NewClassType.Modifiers.Assign(GenClassType.Modifiers);
|
|
// ToDo NewClassType.Interfaces
|
|
// ToDo NewClassType.Interfaces
|
|
NewClassType.ExternalNameSpace:=GenClassType.ExternalNameSpace;
|
|
NewClassType.ExternalNameSpace:=GenClassType.ExternalNameSpace;
|
|
@@ -14494,6 +14600,113 @@ begin
|
|
FinishTypeDef(SpecType);
|
|
FinishTypeDef(SpecType);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPasResolver.SpecializeGenTypeImpl(GenericType: TPasGenericType;
|
|
|
|
+ SpecializedItem: TPSSpecializedItem);
|
|
|
|
+var
|
|
|
|
+ SpecType: TPasGenericType;
|
|
|
|
+ GenClassOrRec, SpecClassOrRec: TPasMembersType;
|
|
|
|
+ GenMember, SpecMember, ImplParent: TPasElement;
|
|
|
|
+ GenIntfProc, GenImplProc, SpecImplProc, SpecIntfProc: TPasProcedure;
|
|
|
|
+ GenIntfProcScope, SpecIntfProcScope, GenImplProcScope,
|
|
|
|
+ SpecImplProcScope: TPasProcedureScope;
|
|
|
|
+ NewClass: TPTreeElement;
|
|
|
|
+ OldStashCount, i: Integer;
|
|
|
|
+ SpecClassOrRecScope: TPasClassOrRecordScope;
|
|
|
|
+ GenScope: TPasGenericScope;
|
|
|
|
+begin
|
|
|
|
+ // check generic type is resolved completely
|
|
|
|
+ GenScope:=TPasGenericScope(GenericType.CustomData);
|
|
|
|
+ if GenScope.GenericStep<psgsImplementationParsed then
|
|
|
|
+ RaiseNotYetImplemented(20190804174019,GenericType,GetObjName(SpecializedItem.SpecializedType));
|
|
|
|
+
|
|
|
|
+ // check specialized type step
|
|
|
|
+ if SpecializedItem.Step<psssInterfaceFinished then
|
|
|
|
+ RaiseNotYetImplemented(20190804120128,GenericType,GetObjName(SpecializedItem.SpecializedType));
|
|
|
|
+ if SpecializedItem.Step>psssInterfaceFinished then
|
|
|
|
+ exit;
|
|
|
|
+ SpecializedItem.Step:=psssImplementationBuilding;
|
|
|
|
+
|
|
|
|
+ SpecType:=SpecializedItem.SpecializedType;
|
|
|
|
+
|
|
|
|
+ // specialize all methods
|
|
|
|
+ if GenericType is TPasMembersType then
|
|
|
|
+ begin
|
|
|
|
+ GenClassOrRec:=TPasMembersType(GenericType);
|
|
|
|
+ SpecClassOrRec:=TPasMembersType(SpecType);
|
|
|
|
+ SpecClassOrRecScope:=TPasClassOrRecordScope(SpecClassOrRec.CustomData);
|
|
|
|
+
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPasResolver.FinishClassType RestoreStashedScopes ',GetObjName(SpecializedItem.SpecializedType),' ',ScopeCount,' FStashScopeCount=',FStashScopeCount);
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ ImplParent:=nil;
|
|
|
|
+ OldStashCount:=FStashScopeCount;
|
|
|
|
+
|
|
|
|
+ for i:=0 to GenClassOrRec.Members.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ GenMember:=TPasElement(GenClassOrRec.Members[i]);
|
|
|
|
+ if GenMember is TPasProcedure then
|
|
|
|
+ begin
|
|
|
|
+ GenIntfProc:=TPasProcedure(GenMember);
|
|
|
|
+ if GenIntfProc.IsAbstract or GenIntfProc.IsExternal then continue;
|
|
|
|
+ GenIntfProcScope:=TPasProcedureScope(GenIntfProc.CustomData);
|
|
|
|
+ GenImplProc:=GenIntfProcScope.ImplProc;
|
|
|
|
+ if GenImplProc=nil then
|
|
|
|
+ RaiseNotYetImplemented(20190804122134,GenIntfProc);
|
|
|
|
+ GenImplProcScope:=TPasProcedureScope(GenImplProc.CustomData);
|
|
|
|
+ SpecMember:=TPasElement(SpecClassOrRec.Members[i]);
|
|
|
|
+ if SpecMember.Name<>GenMember.Name then
|
|
|
|
+ RaiseNotYetImplemented(20190804124220,GenMember,GetObjName(SpecMember));
|
|
|
|
+ SpecIntfProc:=SpecMember as TPasProcedure;
|
|
|
|
+ SpecIntfProcScope:=TPasProcedureScope(SpecIntfProc.CustomData);
|
|
|
|
+ NewClass:=TPTreeElement(GenImplProc.ClassType);
|
|
|
|
+
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPasResolver.SpecializeGenTypeImpl Specialize GenImplProc: ',GetObjName(GenImplProc));
|
|
|
|
+ {$ENDIF}
|
|
|
|
+
|
|
|
|
+ if ImplParent=nil then
|
|
|
|
+ begin
|
|
|
|
+ // switch scope (e.g. unit implementation section)
|
|
|
|
+ ImplParent:=GenImplProc.Parent;
|
|
|
|
+ OldStashCount:=InitSpecializeScopes(ImplParent);
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPasResolver.SpecializeGenTypeImpl Specialize implprocs: ',GetObjName(SpecType),' ',ScopeCount,' FStashScopeCount=',FStashScopeCount,' TopScope=',GetObjName(TopScope));
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ end
|
|
|
|
+ else if ImplParent<>GenImplProc.Parent then
|
|
|
|
+ RaiseNotYetImplemented(20190804130322,GenImplProc,GetObjName(ImplParent));
|
|
|
|
+
|
|
|
|
+ // create impl proc
|
|
|
|
+ SpecImplProc:=TPasProcedure(NewClass.Create(GenImplProc.Name,GenImplProc.Parent));
|
|
|
|
+ SpecIntfProcScope.ImplProc:=SpecImplProc;
|
|
|
|
+ if SpecializedItem.ImplProcs=nil then
|
|
|
|
+ SpecializedItem.ImplProcs:=TFPList.Create;
|
|
|
|
+ SpecializedItem.ImplProcs.Add(SpecImplProc);
|
|
|
|
+
|
|
|
|
+ // create impl proc scope
|
|
|
|
+ SpecImplProcScope:=TPasProcedureScope(CreateScope(SpecImplProc,FScopeClass_Proc));
|
|
|
|
+ SpecImplProcScope.Flags:=[ppsfIsSpecialized];
|
|
|
|
+ SpecImplProcScope.DeclarationProc:=SpecIntfProc;
|
|
|
|
+ SpecImplProcScope.ModeSwitches:=GenImplProcScope.Modeswitches;
|
|
|
|
+ SpecImplProcScope.BoolSwitches:=GenImplProcScope.BoolSwitches;
|
|
|
|
+ SpecImplProcScope.VisibilityContext:=SpecClassOrRec;
|
|
|
|
+ SpecImplProcScope.ClassRecScope:=SpecClassOrRecScope;
|
|
|
|
+
|
|
|
|
+ // specialize props
|
|
|
|
+ SpecializeElement(GenImplProc,SpecImplProc);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if ImplParent<>nil then
|
|
|
|
+ begin
|
|
|
|
+ // restore scope
|
|
|
|
+ RestoreStashedScopes(OldStashCount);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ SpecializedItem.Step:=psssImplementationFinished;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TPasResolver.SpecializeMembers(GenMembersType,
|
|
procedure TPasResolver.SpecializeMembers(GenMembersType,
|
|
SpecMembersType: TPasMembersType);
|
|
SpecMembersType: TPasMembersType);
|
|
var
|
|
var
|
|
@@ -14510,7 +14723,6 @@ begin
|
|
NewEl:=TPasElement(NewClass.Create(GenEl.Name,SpecMembersType));
|
|
NewEl:=TPasElement(NewClass.Create(GenEl.Name,SpecMembersType));
|
|
SpecMembersType.Members.Add(NewEl);
|
|
SpecMembersType.Members.Add(NewEl);
|
|
SpecializeElement(GenEl,NewEl);
|
|
SpecializeElement(GenEl,NewEl);
|
|
- FinishDeclaration(NewEl);
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -14525,7 +14737,29 @@ begin
|
|
if C=TPasVariable then
|
|
if C=TPasVariable then
|
|
begin
|
|
begin
|
|
AddVariable(TPasVariable(SpecEl));
|
|
AddVariable(TPasVariable(SpecEl));
|
|
- SpecializeVariable(TPasVariable(GenEl),TPasVariable(SpecEl))
|
|
|
|
|
|
+ SpecializeVariable(TPasVariable(GenEl),TPasVariable(SpecEl));
|
|
|
|
+ end
|
|
|
|
+ else if C=TPasArgument then
|
|
|
|
+ begin
|
|
|
|
+ AddArgument(TPasArgument(SpecEl));
|
|
|
|
+ SpecializeArgument(TPasArgument(GenEl),TPasArgument(SpecEl));
|
|
|
|
+ end
|
|
|
|
+ else if C=TPasImplBeginBlock then
|
|
|
|
+ SpecializeImplBlock(TPasImplBeginBlock(GenEl),TPasImplBeginBlock(SpecEl))
|
|
|
|
+ else if C=TProcedureBody then
|
|
|
|
+ begin
|
|
|
|
+ AddProcedureBody(TProcedureBody(SpecEl));
|
|
|
|
+ SpecializeProcedureBody(TProcedureBody(GenEl),TProcedureBody(SpecEl));
|
|
|
|
+ end
|
|
|
|
+ else if C.InheritsFrom(TPasProcedure) then
|
|
|
|
+ begin
|
|
|
|
+ AddProcedure(TPasProcedure(SpecEl));
|
|
|
|
+ SpecializeProcedure(TPasProcedure(GenEl),TPasProcedure(SpecEl));
|
|
|
|
+ end
|
|
|
|
+ else if C.InheritsFrom(TPasProcedureType) then
|
|
|
|
+ begin
|
|
|
|
+ AddType(TPasProcedureType(SpecEl));
|
|
|
|
+ SpecializeProcedureType(TPasProcedureType(GenEl),TPasProcedureType(SpecEl));
|
|
end
|
|
end
|
|
else
|
|
else
|
|
RaiseNotYetImplemented(20190728151215,GenEl);
|
|
RaiseNotYetImplemented(20190728151215,GenEl);
|
|
@@ -14547,11 +14781,16 @@ procedure TPasResolver.SpecializeVariable(GenEl, SpecEl: TPasVariable);
|
|
begin
|
|
begin
|
|
SpecializeElType(GenEl,SpecEl,GenEl.VarType,SpecEl.VarType);
|
|
SpecializeElType(GenEl,SpecEl,GenEl.VarType,SpecEl.VarType);
|
|
SpecEl.VarModifiers:=GenEl.VarModifiers;
|
|
SpecEl.VarModifiers:=GenEl.VarModifiers;
|
|
- //LibraryName : TPasExpr; // libname of modifier external
|
|
|
|
- //ExportName : TPasExpr; // symbol name of modifier external, export and public
|
|
|
|
|
|
+ if GenEl.LibraryName<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.LibraryName,SpecEl.LibraryName);
|
|
|
|
+ if GenEl.ExportName<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.ExportName,SpecEl.ExportName);
|
|
SpecEl.Modifiers:=GenEl.Modifiers;
|
|
SpecEl.Modifiers:=GenEl.Modifiers;
|
|
- //AbsoluteExpr: TPasExpr;
|
|
|
|
- //Expr: TPasExpr;
|
|
|
|
|
|
+ if GenEl.AbsoluteExpr<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.AbsoluteExpr,SpecEl.AbsoluteExpr);
|
|
|
|
+ if GenEl.Expr<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.Expr,SpecEl.Expr);
|
|
|
|
+ FinishVariable(SpecEl);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TPasResolver.SpecializeElType(GenEl, SpecEl: TPasElement;
|
|
procedure TPasResolver.SpecializeElType(GenEl, SpecEl: TPasElement;
|
|
@@ -14576,12 +14815,168 @@ begin
|
|
SpecElType.Release{$IFDEF CheckPasTreeRefCount}('ResolveTypeReference'){$ENDIF};
|
|
SpecElType.Release{$IFDEF CheckPasTreeRefCount}('ResolveTypeReference'){$ENDIF};
|
|
SpecElType:=GenElType;
|
|
SpecElType:=GenElType;
|
|
SpecElType.AddRef{$IFDEF CheckPasTreeRefCount}('ResolveTypeReference'){$ENDIF};
|
|
SpecElType.AddRef{$IFDEF CheckPasTreeRefCount}('ResolveTypeReference'){$ENDIF};
|
|
- end
|
|
|
|
- else
|
|
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ // e.g. anonymous type
|
|
|
|
+ RaiseNotYetImplemented(20190728152244,GenEl);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasResolver.SpecializeElExpr(GenEl, SpecEl: TPasElement;
|
|
|
|
+ GenElExpr: TPasExpr; var SpecElExpr: TPasExpr);
|
|
|
|
+begin
|
|
|
|
+ if GenElExpr=nil then exit;
|
|
|
|
+ if GenElExpr.Parent<>GenEl then
|
|
begin
|
|
begin
|
|
- // e.g. anonymous type
|
|
|
|
- RaiseNotYetImplemented(20190728152244,GenEl);
|
|
|
|
|
|
+ // reference
|
|
|
|
+ if SpecElExpr<>nil then
|
|
|
|
+ RaiseNotYetImplemented(20190803220248,SpecEl,GetObjName(SpecElExpr));
|
|
|
|
+ SpecElExpr:=GenElExpr;
|
|
|
|
+ SpecElExpr.AddRef{$IFDEF CheckPasTreeRefCount}('SpecializeElExpr'){$ENDIF};
|
|
|
|
+ exit;
|
|
end;
|
|
end;
|
|
|
|
+ // normal expression
|
|
|
|
+ RaiseNotYetImplemented(20190803220358,GenEl);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasResolver.SpecializeProcedure(GenEl, SpecEl: TPasProcedure);
|
|
|
|
+var
|
|
|
|
+ GenProcType: TPasProcedureType;
|
|
|
|
+ NewClass: TPTreeElement;
|
|
|
|
+ SpecProcScope: TPasProcedureScope;
|
|
|
|
+ GenBody: TProcedureBody;
|
|
|
|
+begin
|
|
|
|
+ SpecializePasElementProperties(GenEl,SpecEl);
|
|
|
|
+
|
|
|
|
+ SpecProcScope:=SpecEl.CustomData as TPasProcedureScope;
|
|
|
|
+ Include(SpecProcScope.Flags,ppsfIsSpecialized);
|
|
|
|
+
|
|
|
|
+ if GenEl.PublicName<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.PublicName,SpecEl.PublicName);
|
|
|
|
+ if GenEl.LibrarySymbolName<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.LibrarySymbolName,SpecEl.LibrarySymbolName);
|
|
|
|
+ if GenEl.LibraryExpr<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.LibraryExpr,SpecEl.LibraryExpr);
|
|
|
|
+ if GenEl.DispIDExpr<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.DispIDExpr,SpecEl.DispIDExpr);
|
|
|
|
+ if GenEl.MessageExpr<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.MessageExpr,SpecEl.MessageExpr);
|
|
|
|
+ SpecEl.MessageName:=GenEl.MessageName;
|
|
|
|
+ SpecEl.MessageType:=GenEl.MessageType;
|
|
|
|
+ SpecEl.AliasName:=GenEl.AliasName;
|
|
|
|
+ SpecEl.Modifiers:=GenEl.Modifiers;
|
|
|
|
+ if GenEl.ProcType<>nil then
|
|
|
|
+ begin
|
|
|
|
+ GenProcType:=GenEl.ProcType;
|
|
|
|
+ if GenProcType.Parent<>GenEl then
|
|
|
|
+ RaiseNotYetImplemented(20190803212426,GenEl,GetObjName(GenProcType.Parent));
|
|
|
|
+ NewClass:=TPTreeElement(GenProcType.ClassType);
|
|
|
|
+ SpecEl.ProcType:=TPasProcedureType(NewClass.Create(GenProcType.Name,SpecEl));
|
|
|
|
+ SpecializeElement(GenProcType,SpecEl.ProcType);
|
|
|
|
+ end;
|
|
|
|
+ if GenEl.Body<>nil then
|
|
|
|
+ begin
|
|
|
|
+ GenBody:=GenEl.Body;
|
|
|
|
+ if GenBody.Parent<>GenEl then
|
|
|
|
+ RaiseNotYetImplemented(20190804183308,GenEl,GetObjName(GenBody.Parent));
|
|
|
|
+ NewClass:=TPTreeElement(GenBody.ClassType);
|
|
|
|
+ SpecEl.Body:=TProcedureBody(NewClass.Create(GenBody.Name,SpecEl));
|
|
|
|
+ SpecializeElement(GenBody,SpecEl.Body);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if length(GenEl.NameParts)>0 then RaiseNotYetImplemented(20190803215418,GenEl);
|
|
|
|
+
|
|
|
|
+ FinishProcedure(SpecEl);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasResolver.SpecializeProcedureType(GenEl, SpecEl: TPasProcedureType
|
|
|
|
+ );
|
|
|
|
+var
|
|
|
|
+ GenResultEl, NewResultEl: TPasResultElement;
|
|
|
|
+ NewClass: TPTreeElement;
|
|
|
|
+ i: Integer;
|
|
|
|
+ GenArg, NewArg: TPasArgument;
|
|
|
|
+begin
|
|
|
|
+ // Args
|
|
|
|
+ for i:=0 to GenEl.Args.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ GenArg:=TPasArgument(GenEl.Args[i]);
|
|
|
|
+ if GenArg.Parent<>GenEl then
|
|
|
|
+ RaiseNotYetImplemented(20190803213700,GenArg,GetObjName(GenArg.Parent));
|
|
|
|
+ NewClass:=TPTreeElement(GenArg.ClassType);
|
|
|
|
+ NewArg:=TPasArgument(NewClass.Create(GenArg.Name,SpecEl));
|
|
|
|
+ SpecEl.Args.Add(NewArg);
|
|
|
|
+ SpecializeElement(GenArg,NewArg);
|
|
|
|
+ end;
|
|
|
|
+ // properties
|
|
|
|
+ SpecEl.CallingConvention:=GenEl.CallingConvention;
|
|
|
|
+ SpecEl.Modifiers:=GenEl.Modifiers;
|
|
|
|
+
|
|
|
|
+ // function result
|
|
|
|
+ if SpecEl is TPasFunctionType then
|
|
|
|
+ begin
|
|
|
|
+ GenResultEl:=TPasFunctionType(GenEl).ResultEl;
|
|
|
|
+ if GenResultEl.Parent<>GenEl then
|
|
|
|
+ RaiseNotYetImplemented(20190803212935,GenEl,GetObjName(GenResultEl.Parent));
|
|
|
|
+ NewClass:=TPTreeElement(GenResultEl.ClassType);
|
|
|
|
+ NewResultEl:=TPasResultElement(NewClass.Create(GenResultEl.Name,SpecEl));
|
|
|
|
+ TPasFunctionType(SpecEl).ResultEl:=NewResultEl;
|
|
|
|
+ SpecializeElType(GenResultEl,NewResultEl,GenResultEl.ResultType,NewResultEl.ResultType);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ FinishProcedureType(SpecEl);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasResolver.SpecializeProcedureBody(GenEl, SpecEl: TProcedureBody);
|
|
|
|
+var
|
|
|
|
+ GenBody, NewBody: TPasImplBlock;
|
|
|
|
+ NewClass: TPTreeElement;
|
|
|
|
+begin
|
|
|
|
+ SpecializeDeclarations(GenEl,SpecEl);
|
|
|
|
+
|
|
|
|
+ if GenEl.Body<>nil then
|
|
|
|
+ begin
|
|
|
|
+ GenBody:=GenEl.Body;
|
|
|
|
+ if GenBody.Parent<>GenEl then
|
|
|
|
+ RaiseNotYetImplemented(20190804184934,GenBody);
|
|
|
|
+ NewClass:=TPTreeElement(GenBody.ClassType);
|
|
|
|
+ NewBody:=TPasImplBlock(NewClass.Create(GenBody.Name,SpecEl));
|
|
|
|
+ SpecEl.Body:=NewBody;
|
|
|
|
+ SpecializeElement(GenBody,NewBody);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasResolver.SpecializeDeclarations(GenEl, SpecEl: TPasDeclarations);
|
|
|
|
+begin
|
|
|
|
+ if SpecEl=nil then ;
|
|
|
|
+ if GenEl.Declarations.Count>0 then
|
|
|
|
+ RaiseNotYetImplemented(20190804184718,GenEl);
|
|
|
|
+ //ToDo: Declarations: TFPList; // list of TPasElement
|
|
|
|
+ //ToDo: Attributes, // TPasAttributes
|
|
|
|
+ //ToDo: Classes, // TPasClassType, TPasRecordType
|
|
|
|
+ //ToDo: Consts, // TPasConst
|
|
|
|
+ //ToDo: ExportSymbols,// TPasExportSymbol
|
|
|
|
+ //ToDo: Functions, // TPasProcedure
|
|
|
|
+ //ToDo: Properties, // TPasProperty
|
|
|
|
+ //ToDo: ResStrings, // TPasResString
|
|
|
|
+ //ToDo: Types, // TPasType, except TPasClassType, TPasRecordType
|
|
|
|
+ //ToDo: Variables // TPasVariable, not descendants
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasResolver.SpecializeArgument(GenEl, SpecEl: TPasArgument);
|
|
|
|
+begin
|
|
|
|
+ SpecEl.Access:=GenEl.Access;
|
|
|
|
+ SpecializeElType(GenEl,SpecEl,GenEl.ArgType,SpecEl.ArgType);
|
|
|
|
+ if GenEl.ValueExpr<>nil then
|
|
|
|
+ SpecializeElExpr(GenEl,SpecEl,GenEl.ValueExpr,SpecEl.ValueExpr);
|
|
|
|
+
|
|
|
|
+ FinishArgument(SpecEl);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasResolver.SpecializeImplBlock(GenEl, SpecEl: TPasImplBlock);
|
|
|
|
+begin
|
|
|
|
+ if SpecEl=nil then ;
|
|
|
|
+ if GenEl.Elements.Count>0 then
|
|
|
|
+ RaiseNotYetImplemented(20190804185503,GenEl);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TPasResolver.CheckAssignCompatibilityCustom(const LHS,
|
|
function TPasResolver.CheckAssignCompatibilityCustom(const LHS,
|