mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 07:46:00 +02:00
pas2js: rename overloads in specialized members
git-svn-id: trunk@45563 -
This commit is contained in:
parent
a03ed979fd
commit
f94221d788
@ -1131,6 +1131,7 @@ type
|
|||||||
TPas2JSSectionScope = class(TPasSectionScope)
|
TPas2JSSectionScope = class(TPasSectionScope)
|
||||||
public
|
public
|
||||||
ElevatedLocals: TPas2jsElevatedLocals;
|
ElevatedLocals: TPas2jsElevatedLocals;
|
||||||
|
Renamed: boolean;
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure WriteElevatedLocals(Prefix: string); virtual;
|
procedure WriteElevatedLocals(Prefix: string); virtual;
|
||||||
@ -1151,22 +1152,31 @@ type
|
|||||||
public
|
public
|
||||||
NewInstanceFunction: TPasClassFunction;
|
NewInstanceFunction: TPasClassFunction;
|
||||||
GUID: string;
|
GUID: string;
|
||||||
|
ElevatedLocals: TPas2jsElevatedLocals;
|
||||||
|
MemberOverloadsRenamed: boolean;
|
||||||
// Dispatch and message modifiers:
|
// Dispatch and message modifiers:
|
||||||
DispatchField: String;
|
DispatchField: String;
|
||||||
DispatchStrField: String;
|
DispatchStrField: String;
|
||||||
MsgIntToProc, MsgStrToProc: TMessageIdToProc_List; // not stored by filer
|
MsgIntToProc, MsgStrToProc: TMessageIdToProc_List; // not stored by filer
|
||||||
ElevatedLocals: TPas2jsElevatedLocals;
|
|
||||||
public
|
public
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TPas2JSRecordScope }
|
||||||
|
|
||||||
|
TPas2JSRecordScope = class(TPasRecordScope)
|
||||||
|
public
|
||||||
|
MemberOverloadsRenamed: boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPas2JSProcedureScope }
|
{ TPas2JSProcedureScope }
|
||||||
|
|
||||||
TPas2JSProcedureScope = class(TPasProcedureScope)
|
TPas2JSProcedureScope = class(TPasProcedureScope)
|
||||||
public
|
public
|
||||||
OverloadName: string;
|
OverloadName: string;
|
||||||
ResultVarName: string; // valid in implementation ProcScope, empty means use ResolverResultVar
|
ResultVarName: string; // valid in implementation ProcScope, empty means use ResolverResultVar
|
||||||
|
BodyOverloadsRenamed: boolean;
|
||||||
BodyJS: string; // Option coStoreProcJS: stored in ImplScope
|
BodyJS: string; // Option coStoreProcJS: stored in ImplScope
|
||||||
GlobalJS: TStringList; // Option coStoreProcJS: stored in ImplScope
|
GlobalJS: TStringList; // Option coStoreProcJS: stored in ImplScope
|
||||||
EmptyJS: boolean; // Option coStoreProcJS: stored in ImplScope, true if Body.Body=nil
|
EmptyJS: boolean; // Option coStoreProcJS: stored in ImplScope, true if Body.Body=nil
|
||||||
@ -1371,9 +1381,12 @@ type
|
|||||||
procedure RenameOverloadsInSection(aSection: TPasSection);
|
procedure RenameOverloadsInSection(aSection: TPasSection);
|
||||||
procedure RenameOverloads(DeclEl: TPasElement; Declarations: TFPList);
|
procedure RenameOverloads(DeclEl: TPasElement; Declarations: TFPList);
|
||||||
procedure RenameSubOverloads(Declarations: TFPList);
|
procedure RenameSubOverloads(Declarations: TFPList);
|
||||||
|
procedure RenameMembers(El: TPasMembersType);
|
||||||
procedure PushOverloadScopeSkip;
|
procedure PushOverloadScopeSkip;
|
||||||
procedure PushOverloadScope(Scope: TPasIdentifierScope);
|
procedure PushOverloadScope(Scope: TPasIdentifierScope);
|
||||||
|
function PushOverloadClassOrRecScopes(Scope: TPasClassOrRecordScope; WithParents: boolean): integer;
|
||||||
procedure PopOverloadScope;
|
procedure PopOverloadScope;
|
||||||
|
procedure RestoreOverloadScopeLvl(OldScopeCount: integer);
|
||||||
procedure ClearOverloadScopes;
|
procedure ClearOverloadScopes;
|
||||||
protected
|
protected
|
||||||
procedure AddType(El: TPasType); override;
|
procedure AddType(El: TPasType); override;
|
||||||
@ -1417,6 +1430,10 @@ type
|
|||||||
procedure AddElevatedLocal(El: TPasElement); virtual;
|
procedure AddElevatedLocal(El: TPasElement); virtual;
|
||||||
procedure ClearElementData; virtual;
|
procedure ClearElementData; virtual;
|
||||||
function GenerateGUID(El: TPasClassType): string; virtual;
|
function GenerateGUID(El: TPasClassType): string; virtual;
|
||||||
|
protected
|
||||||
|
// generic/specialize
|
||||||
|
procedure SpecializeGenericImpl(SpecializedItem: TPRSpecializedItem);
|
||||||
|
override;
|
||||||
protected
|
protected
|
||||||
const
|
const
|
||||||
cJSValueConversion = 2*cTypeConversion;
|
cJSValueConversion = 2*cTypeConversion;
|
||||||
@ -3027,7 +3044,7 @@ var
|
|||||||
ElevatedLocals: TPas2jsElevatedLocals;
|
ElevatedLocals: TPas2jsElevatedLocals;
|
||||||
begin
|
begin
|
||||||
Result:=0;
|
Result:=0;
|
||||||
//if SameText(El.Name,'ci') then writeln('TPas2JSResolver.GetOverloadIndex ',GetObjPath(El),' ',HasOverloadIndex(El,true));
|
//if SameText(El.Name,'ci') then writeln('TPas2JSResolver.GetOverloadIndex ',GetObjPath(El),' HasOverloadIndex=',HasOverloadIndex(El,true));
|
||||||
if not HasOverloadIndex(El,true) then exit;
|
if not HasOverloadIndex(El,true) then exit;
|
||||||
|
|
||||||
ThisChanged:=false;
|
ThisChanged:=false;
|
||||||
@ -3048,7 +3065,7 @@ begin
|
|||||||
|
|
||||||
// check elevated locals
|
// check elevated locals
|
||||||
ElevatedLocals:=GetElevatedLocals(Scope);
|
ElevatedLocals:=GetElevatedLocals(Scope);
|
||||||
// if SameText(El.Name,'ci') then writeln('TPas2JSResolver.GetOverloadIndex ',GetObjPath(El),' ',Scope.Element.ClassName,' ',ElevatedLocals<>nil);
|
//if SameText(El.Name,'ci') then writeln('TPas2JSResolver.GetOverloadIndex ',GetObjPath(El),' Scope.Element=',GetObjName(Scope.Element),' ',ElevatedLocals<>nil);
|
||||||
if ElevatedLocals<>nil then
|
if ElevatedLocals<>nil then
|
||||||
begin
|
begin
|
||||||
Identifier:=ElevatedLocals.Find(El.Name);
|
Identifier:=ElevatedLocals.Find(El.Name);
|
||||||
@ -3074,7 +3091,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if ThisChanged then exit;
|
if ThisChanged then exit;
|
||||||
// finally add count or index of the external scope
|
// element in global scope
|
||||||
|
// -> add count or index of the external scope
|
||||||
Identifier:=FindExternalName(El.Name);
|
Identifier:=FindExternalName(El.Name);
|
||||||
inc(Result,GetOverloadIndex(Identifier,El));
|
inc(Result,GetOverloadIndex(Identifier,El));
|
||||||
end;
|
end;
|
||||||
@ -3199,9 +3217,16 @@ end;
|
|||||||
procedure TPas2JSResolver.RenameOverloadsInSection(aSection: TPasSection);
|
procedure TPas2JSResolver.RenameOverloadsInSection(aSection: TPasSection);
|
||||||
var
|
var
|
||||||
IntfSection: TInterfaceSection;
|
IntfSection: TInterfaceSection;
|
||||||
|
OldScopeCount: Integer;
|
||||||
|
Scope: TPas2JSSectionScope;
|
||||||
begin
|
begin
|
||||||
if aSection=nil then exit;
|
if aSection=nil then exit;
|
||||||
|
Scope:=aSection.CustomData as TPas2JSSectionScope;
|
||||||
|
if Scope.Renamed then
|
||||||
|
RaiseNotYetImplemented(20200601231236,aSection);
|
||||||
|
|
||||||
IntfSection:=nil;
|
IntfSection:=nil;
|
||||||
|
OldScopeCount:=FOverloadScopes.Count;
|
||||||
if aSection.ClassType=TImplementationSection then
|
if aSection.ClassType=TImplementationSection then
|
||||||
begin
|
begin
|
||||||
IntfSection:=RootElement.InterfaceSection;
|
IntfSection:=RootElement.InterfaceSection;
|
||||||
@ -3210,9 +3235,8 @@ begin
|
|||||||
PushOverloadScope(aSection.CustomData as TPasIdentifierScope);
|
PushOverloadScope(aSection.CustomData as TPasIdentifierScope);
|
||||||
RenameOverloads(aSection,aSection.Declarations);
|
RenameOverloads(aSection,aSection.Declarations);
|
||||||
RenameSubOverloads(aSection.Declarations);
|
RenameSubOverloads(aSection.Declarations);
|
||||||
PopOverloadScope;
|
RestoreOverloadScopeLvl(OldScopeCount);
|
||||||
if IntfSection<>nil then
|
Scope.Renamed:=true;
|
||||||
PopOverloadScope;
|
|
||||||
{$IFDEF VerbosePas2JS}
|
{$IFDEF VerbosePas2JS}
|
||||||
//writeln('TPas2JSResolver.RenameOverloadsInSection END ',GetObjName(aSection));
|
//writeln('TPas2JSResolver.RenameOverloadsInSection END ',GetObjName(aSection));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -3286,51 +3310,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPas2JSResolver.RenameSubOverloads(Declarations: TFPList);
|
procedure TPas2JSResolver.RenameSubOverloads(Declarations: TFPList);
|
||||||
|
|
||||||
procedure RestoreScopeLvl(OldScopeCount: integer);
|
|
||||||
begin
|
|
||||||
while FOverloadScopes.Count>OldScopeCount do
|
|
||||||
PopOverloadScope;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure LocalPushClassOrRecScopes(Scope: TPasClassOrRecordScope);
|
|
||||||
var
|
|
||||||
CurScope: TPasClassOrRecordScope;
|
|
||||||
aParent: TPasElement;
|
|
||||||
begin
|
|
||||||
CurScope:=Scope;
|
|
||||||
repeat
|
|
||||||
PushOverloadScope(CurScope);
|
|
||||||
if Scope is TPas2JSClassScope then
|
|
||||||
CurScope:=TPas2JSClassScope(CurScope).AncestorScope
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
until CurScope=nil;
|
|
||||||
aParent:=Scope.Element.Parent;
|
|
||||||
if not (aParent is TPasMembersType) then
|
|
||||||
exit;
|
|
||||||
// nested class -> push parent class scope...
|
|
||||||
CurScope:=aParent.CustomData as TPasClassOrRecordScope;
|
|
||||||
LocalPushClassOrRecScopes(CurScope);
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
i, OldScopeCount: Integer;
|
i, OldScopeCount: Integer;
|
||||||
El: TPasElement;
|
El: TPasElement;
|
||||||
Proc, ImplProc: TPasProcedure;
|
Proc, ImplProc: TPasProcedure;
|
||||||
ProcScope, ImplProcScope: TPas2JSProcedureScope;
|
ProcScope, ImplProcScope: TPas2JSProcedureScope;
|
||||||
ClassScope, aScope: TPasClassScope;
|
|
||||||
ClassEl: TPasClassType;
|
|
||||||
C: TClass;
|
C: TClass;
|
||||||
ProcBody: TProcedureBody;
|
ProcBody: TProcedureBody;
|
||||||
IntfSection: TInterfaceSection;
|
|
||||||
ImplSection: TImplementationSection;
|
|
||||||
begin
|
begin
|
||||||
IntfSection:=RootElement.InterfaceSection;
|
|
||||||
if IntfSection<>nil then
|
|
||||||
ImplSection:=RootElement.ImplementationSection
|
|
||||||
else
|
|
||||||
ImplSection:=nil;
|
|
||||||
for i:=0 to Declarations.Count-1 do
|
for i:=0 to Declarations.Count-1 do
|
||||||
begin
|
begin
|
||||||
El:=TPasElement(Declarations[i]);
|
El:=TPasElement(Declarations[i]);
|
||||||
@ -3340,18 +3327,6 @@ begin
|
|||||||
Proc:=TPasProcedure(El);
|
Proc:=TPasProcedure(El);
|
||||||
ProcScope:=Proc.CustomData as TPas2JSProcedureScope;
|
ProcScope:=Proc.CustomData as TPas2JSProcedureScope;
|
||||||
|
|
||||||
// handle each Proc only once, by handling only the DeclProc,
|
|
||||||
// except for DeclProc in the unit interface
|
|
||||||
if ProcScope.DeclarationProc<>nil then
|
|
||||||
begin
|
|
||||||
// ImplProc with separate declaration
|
|
||||||
if (Proc.Parent=ImplSection)
|
|
||||||
and ProcScope.DeclarationProc.HasParent(IntfSection) then
|
|
||||||
// ImplProc in unit implementation, DeclProc in unit interface
|
|
||||||
// Note: The Unit Impl elements are renamed in a separate run, aka now
|
|
||||||
else
|
|
||||||
continue; // handled via DeclProc
|
|
||||||
end;
|
|
||||||
ImplProc:=ProcScope.ImplProc;
|
ImplProc:=ProcScope.ImplProc;
|
||||||
if ImplProc<>nil then
|
if ImplProc<>nil then
|
||||||
ImplProcScope:=TPas2JSProcedureScope(ImplProc.CustomData)
|
ImplProcScope:=TPas2JSProcedureScope(ImplProc.CustomData)
|
||||||
@ -3364,62 +3339,71 @@ begin
|
|||||||
//writeln('TPas2JSResolver.RenameSubOverloads ImplProc=',ImplProc.Name,' DeclarationProc=',GetObjName(ProcScope.DeclarationProc),' ClassScope=',GetObjName(ImplProcScope.ClassOrRecordScope));
|
//writeln('TPas2JSResolver.RenameSubOverloads ImplProc=',ImplProc.Name,' DeclarationProc=',GetObjName(ProcScope.DeclarationProc),' ClassScope=',GetObjName(ImplProcScope.ClassOrRecordScope));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
ProcBody:=ImplProc.Body;
|
ProcBody:=ImplProc.Body;
|
||||||
if ProcBody<>nil then
|
if (ProcBody<>nil) and (not ImplProcScope.BodyOverloadsRenamed) then
|
||||||
begin
|
begin
|
||||||
|
ImplProcScope.BodyOverloadsRenamed:=true;
|
||||||
OldScopeCount:=FOverloadScopes.Count;
|
OldScopeCount:=FOverloadScopes.Count;
|
||||||
if (ImplProcScope.ClassRecScope<>nil)
|
if (ImplProcScope.ClassRecScope<>nil)
|
||||||
and not (Proc.Parent is TPasMembersType) then
|
and not (Proc.Parent is TPasMembersType) then
|
||||||
begin
|
begin
|
||||||
// push class scopes
|
// push class scopes
|
||||||
LocalPushClassOrRecScopes(ImplProcScope.ClassRecScope);
|
PushOverloadClassOrRecScopes(ImplProcScope.ClassRecScope,true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
PushOverloadScope(ImplProcScope);
|
PushOverloadScope(ImplProcScope);
|
||||||
// first rename all overloads on this level
|
// first rename all overloads on this level
|
||||||
RenameOverloads(ProcBody,ProcBody.Declarations);
|
RenameOverloads(ProcBody,ProcBody.Declarations);
|
||||||
// then process nested procedures
|
// then process nested procedures
|
||||||
RenameSubOverloads(ProcBody.Declarations);
|
RenameSubOverloads(ProcBody.Declarations);
|
||||||
PopOverloadScope;
|
PopOverloadScope;
|
||||||
RestoreScopeLvl(OldScopeCount);
|
RestoreOverloadScopeLvl(OldScopeCount);
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else if (C=TPasClassType) or (C=TPasRecordType) then
|
else if (C=TPasClassType) or (C=TPasRecordType) then
|
||||||
begin
|
RenameMembers(TPasMembersType(El));
|
||||||
OldScopeCount:=FOverloadScopes.Count;
|
|
||||||
if C=TPasClassType then
|
|
||||||
begin
|
|
||||||
ClassEl:=TPasClassType(El);
|
|
||||||
if ClassEl.IsForward then continue;
|
|
||||||
ClassScope:=El.CustomData as TPas2JSClassScope;
|
|
||||||
// add class and ancestor scopes
|
|
||||||
PushOverloadScopeSkip;
|
|
||||||
aScope:=ClassScope;
|
|
||||||
repeat
|
|
||||||
PushOverloadScope(aScope);
|
|
||||||
aScope:=aScope.AncestorScope;
|
|
||||||
until aScope=nil;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
// add record scope
|
|
||||||
PushOverloadScopeSkip;
|
|
||||||
PushOverloadScope(TPasRecordType(El).CustomData as TPasRecordScope);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// first rename all overloads on this level
|
|
||||||
RenameOverloads(El,TPasMembersType(El).Members);
|
|
||||||
// then process nested procedures
|
|
||||||
RenameSubOverloads(TPasMembersType(El).Members);
|
|
||||||
|
|
||||||
// restore scope
|
|
||||||
RestoreScopeLvl(OldScopeCount);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
{$IFDEF VerbosePas2JS}
|
{$IFDEF VerbosePas2JS}
|
||||||
//writeln('TPas2JSResolver.RenameSubOverloads END');
|
//writeln('TPas2JSResolver.RenameSubOverloads END');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPas2JSResolver.RenameMembers(El: TPasMembersType);
|
||||||
|
var
|
||||||
|
OldScopeCount: Integer;
|
||||||
|
ClassEl: TPasClassType;
|
||||||
|
ClassOrRecScope: TPasClassOrRecordScope;
|
||||||
|
RecScope: TPas2JSRecordScope;
|
||||||
|
ClassScope: TPas2JSClassScope;
|
||||||
|
begin
|
||||||
|
OldScopeCount:=FOverloadScopes.Count;
|
||||||
|
if El.ClassType=TPasClassType then
|
||||||
|
begin
|
||||||
|
ClassEl:=TPasClassType(El);
|
||||||
|
if ClassEl.IsForward then exit;
|
||||||
|
// add class and ancestor scopes
|
||||||
|
ClassScope:=El.CustomData as TPas2JSClassScope;
|
||||||
|
if ClassScope.MemberOverloadsRenamed then exit;
|
||||||
|
ClassScope.MemberOverloadsRenamed:=true;
|
||||||
|
ClassOrRecScope:=ClassScope;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// add record scope
|
||||||
|
RecScope:=El.CustomData as TPas2JSRecordScope;
|
||||||
|
if RecScope.MemberOverloadsRenamed then exit;
|
||||||
|
RecScope.MemberOverloadsRenamed:=true;
|
||||||
|
ClassOrRecScope:=RecScope;
|
||||||
|
end;
|
||||||
|
PushOverloadClassOrRecScopes(ClassOrRecScope,false);
|
||||||
|
|
||||||
|
// first rename all overloads on this level
|
||||||
|
RenameOverloads(El,El.Members);
|
||||||
|
// then process nested procedures
|
||||||
|
RenameSubOverloads(El.Members);
|
||||||
|
|
||||||
|
// restore scope
|
||||||
|
RestoreOverloadScopeLvl(OldScopeCount);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPas2JSResolver.PushOverloadScopeSkip;
|
procedure TPas2JSResolver.PushOverloadScopeSkip;
|
||||||
begin
|
begin
|
||||||
FOverloadScopes.Add(TPas2JSOverloadChgThisScope.Create);
|
FOverloadScopes.Add(TPas2JSOverloadChgThisScope.Create);
|
||||||
@ -3427,9 +3411,40 @@ end;
|
|||||||
|
|
||||||
procedure TPas2JSResolver.PushOverloadScope(Scope: TPasIdentifierScope);
|
procedure TPas2JSResolver.PushOverloadScope(Scope: TPasIdentifierScope);
|
||||||
begin
|
begin
|
||||||
|
if (FOverloadScopes.Count>0) and (TObject(FOverloadScopes[FOverloadScopes.Count-1])=Scope) then
|
||||||
|
RaiseNotYetImplemented(20200602000045,Scope.Element);
|
||||||
FOverloadScopes.Add(Scope);
|
FOverloadScopes.Add(Scope);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPas2JSResolver.PushOverloadClassOrRecScopes(
|
||||||
|
Scope: TPasClassOrRecordScope; WithParents: boolean): integer;
|
||||||
|
var
|
||||||
|
CurScope: TPasClassOrRecordScope;
|
||||||
|
aParent: TPasElement;
|
||||||
|
begin
|
||||||
|
Result:=FOverloadScopes.Count;
|
||||||
|
repeat
|
||||||
|
PushOverloadScopeSkip;
|
||||||
|
// push class and ancestors
|
||||||
|
CurScope:=Scope;
|
||||||
|
repeat
|
||||||
|
PushOverloadScope(CurScope);
|
||||||
|
if CurScope is TPas2JSClassScope then
|
||||||
|
CurScope:=TPas2JSClassScope(CurScope).AncestorScope
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
until CurScope=nil;
|
||||||
|
|
||||||
|
if not WithParents then
|
||||||
|
exit;
|
||||||
|
aParent:=Scope.Element.Parent;
|
||||||
|
if not (aParent is TPasMembersType) then
|
||||||
|
exit;
|
||||||
|
// nested class -> push parent class scope...
|
||||||
|
Scope:=aParent.CustomData as TPasClassOrRecordScope;
|
||||||
|
until false;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPas2JSResolver.PopOverloadScope;
|
procedure TPas2JSResolver.PopOverloadScope;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -3442,6 +3457,12 @@ begin
|
|||||||
FOverloadScopes.Delete(i);
|
FOverloadScopes.Delete(i);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPas2JSResolver.RestoreOverloadScopeLvl(OldScopeCount: integer);
|
||||||
|
begin
|
||||||
|
while FOverloadScopes.Count>OldScopeCount do
|
||||||
|
PopOverloadScope;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPas2JSResolver.ClearOverloadScopes;
|
procedure TPas2JSResolver.ClearOverloadScopes;
|
||||||
begin
|
begin
|
||||||
if FOverloadScopes=nil then exit;
|
if FOverloadScopes=nil then exit;
|
||||||
@ -4765,6 +4786,24 @@ begin
|
|||||||
Result:=Result+'}';
|
Result:=Result+'}';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPas2JSResolver.SpecializeGenericImpl(
|
||||||
|
SpecializedItem: TPRSpecializedItem);
|
||||||
|
begin
|
||||||
|
inherited SpecializeGenericImpl(SpecializedItem);
|
||||||
|
if SpecializedItem.SpecializedEl is TPasMembersType then
|
||||||
|
begin
|
||||||
|
if FOverloadScopes=nil then
|
||||||
|
begin
|
||||||
|
FOverloadScopes:=TFPList.Create;
|
||||||
|
try
|
||||||
|
RenameMembers(TPasMembersType(SpecializedItem.SpecializedEl));
|
||||||
|
finally
|
||||||
|
ClearOverloadScopes;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPas2JSResolver.AddJSBaseType(const aName: string; Typ: TPas2jsBaseType
|
function TPas2JSResolver.AddJSBaseType(const aName: string; Typ: TPas2jsBaseType
|
||||||
): TResElDataPas2JSBaseType;
|
): TResElDataPas2JSBaseType;
|
||||||
var
|
var
|
||||||
@ -5554,6 +5593,7 @@ begin
|
|||||||
ScopeClass_InitialFinalization:=TPas2JSInitialFinalizationScope;
|
ScopeClass_InitialFinalization:=TPas2JSInitialFinalizationScope;
|
||||||
ScopeClass_Module:=TPas2JSModuleScope;
|
ScopeClass_Module:=TPas2JSModuleScope;
|
||||||
ScopeClass_Procedure:=TPas2JSProcedureScope;
|
ScopeClass_Procedure:=TPas2JSProcedureScope;
|
||||||
|
ScopeClass_Record:=TPas2JSRecordScope;
|
||||||
ScopeClass_Section:=TPas2JSSectionScope;
|
ScopeClass_Section:=TPas2JSSectionScope;
|
||||||
ScopeClass_WithExpr:=TPas2JSWithExprScope;
|
ScopeClass_WithExpr:=TPas2JSWithExprScope;
|
||||||
for bt in [pbtJSValue] do
|
for bt in [pbtJSValue] do
|
||||||
|
@ -844,7 +844,7 @@ type
|
|||||||
procedure WriteEnumType(Obj: TJSONObject; El: TPasEnumType; aContext: TPCUWriterContext); virtual;
|
procedure WriteEnumType(Obj: TJSONObject; El: TPasEnumType; aContext: TPCUWriterContext); virtual;
|
||||||
procedure WriteSetType(Obj: TJSONObject; El: TPasSetType; aContext: TPCUWriterContext); virtual;
|
procedure WriteSetType(Obj: TJSONObject; El: TPasSetType; aContext: TPCUWriterContext); virtual;
|
||||||
procedure WriteRecordVariant(Obj: TJSONObject; El: TPasVariant; aContext: TPCUWriterContext); virtual;
|
procedure WriteRecordVariant(Obj: TJSONObject; El: TPasVariant; aContext: TPCUWriterContext); virtual;
|
||||||
procedure WriteRecordTypeScope(Obj: TJSONObject; Scope: TPasRecordScope; aContext: TPCUWriterContext); virtual;
|
procedure WriteRecordTypeScope(Obj: TJSONObject; Scope: TPas2jsRecordScope; aContext: TPCUWriterContext); virtual;
|
||||||
procedure WriteRecordType(Obj: TJSONObject; El: TPasRecordType; aContext: TPCUWriterContext); virtual;
|
procedure WriteRecordType(Obj: TJSONObject; El: TPasRecordType; aContext: TPCUWriterContext); virtual;
|
||||||
procedure WriteClassScopeFlags(Obj: TJSONObject; const PropName: string; const Value, DefaultValue: TPasClassScopeFlags); virtual;
|
procedure WriteClassScopeFlags(Obj: TJSONObject; const PropName: string; const Value, DefaultValue: TPasClassScopeFlags); virtual;
|
||||||
procedure WriteClassIntfMapProcs(Obj: TJSONObject; Map: TPasClassIntfMap); virtual;
|
procedure WriteClassIntfMapProcs(Obj: TJSONObject; Map: TPasClassIntfMap); virtual;
|
||||||
@ -1137,7 +1137,7 @@ type
|
|||||||
procedure ReadSetType(Obj: TJSONObject; El: TPasSetType; aContext: TPCUReaderContext); virtual;
|
procedure ReadSetType(Obj: TJSONObject; El: TPasSetType; aContext: TPCUReaderContext); virtual;
|
||||||
function ReadPackedMode(Obj: TJSONObject; const PropName: string; ErrorEl: TPasElement): TPackMode; virtual;
|
function ReadPackedMode(Obj: TJSONObject; const PropName: string; ErrorEl: TPasElement): TPackMode; virtual;
|
||||||
procedure ReadRecordVariant(Obj: TJSONObject; El: TPasVariant; aContext: TPCUReaderContext); virtual;
|
procedure ReadRecordVariant(Obj: TJSONObject; El: TPasVariant; aContext: TPCUReaderContext); virtual;
|
||||||
procedure ReadRecordScope(Obj: TJSONObject; Scope: TPasRecordScope; aContext: TPCUReaderContext); virtual;
|
procedure ReadRecordScope(Obj: TJSONObject; Scope: TPas2jsRecordScope; aContext: TPCUReaderContext); virtual;
|
||||||
procedure ReadRecordType(Obj: TJSONObject; El: TPasRecordType; aContext: TPCUReaderContext); virtual;
|
procedure ReadRecordType(Obj: TJSONObject; El: TPasRecordType; aContext: TPCUReaderContext); virtual;
|
||||||
function ReadClassInterfaceType(Obj: TJSONObject; const PropName: string; ErrorEl: TPasElement; DefaultValue: TPasClassInterfaceType): TPasClassInterfaceType;
|
function ReadClassInterfaceType(Obj: TJSONObject; const PropName: string; ErrorEl: TPasElement; DefaultValue: TPasClassInterfaceType): TPasClassInterfaceType;
|
||||||
function ReadClassScopeFlags(Obj: TJSONObject; El: TPasElement;
|
function ReadClassScopeFlags(Obj: TJSONObject; El: TPasElement;
|
||||||
@ -4038,7 +4038,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPCUWriter.WriteRecordTypeScope(Obj: TJSONObject;
|
procedure TPCUWriter.WriteRecordTypeScope(Obj: TJSONObject;
|
||||||
Scope: TPasRecordScope; aContext: TPCUWriterContext);
|
Scope: TPas2jsRecordScope; aContext: TPCUWriterContext);
|
||||||
begin
|
begin
|
||||||
AddReferenceToObj(Obj,'DefaultProperty',Scope.DefaultProperty);
|
AddReferenceToObj(Obj,'DefaultProperty',Scope.DefaultProperty);
|
||||||
WriteIdentifierScope(Obj,Scope,aContext);
|
WriteIdentifierScope(Obj,Scope,aContext);
|
||||||
@ -4059,7 +4059,7 @@ begin
|
|||||||
WriteElementProperty(Obj,El,'VariantEl',El.VariantEl,aContext);
|
WriteElementProperty(Obj,El,'VariantEl',El.VariantEl,aContext);
|
||||||
WriteElementList(Obj,El,'Variants',El.Variants,aContext);
|
WriteElementList(Obj,El,'Variants',El.Variants,aContext);
|
||||||
|
|
||||||
WriteRecordTypeScope(Obj,El.CustomData as TPasRecordScope,aContext);
|
WriteRecordTypeScope(Obj,El.CustomData as TPas2jsRecordScope,aContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPCUWriter.WriteClassScopeFlags(Obj: TJSONObject;
|
procedure TPCUWriter.WriteClassScopeFlags(Obj: TJSONObject;
|
||||||
@ -5076,7 +5076,7 @@ end;
|
|||||||
procedure TPCUReader.Set_RecordScope_DefaultProperty(RefEl: TPasElement;
|
procedure TPCUReader.Set_RecordScope_DefaultProperty(RefEl: TPasElement;
|
||||||
Data: TObject);
|
Data: TObject);
|
||||||
var
|
var
|
||||||
Scope: TPasRecordScope absolute Data;
|
Scope: TPas2jsRecordScope absolute Data;
|
||||||
begin
|
begin
|
||||||
if RefEl is TPasProperty then
|
if RefEl is TPasProperty then
|
||||||
Scope.DefaultProperty:=TPasProperty(RefEl) // no AddRef
|
Scope.DefaultProperty:=TPasProperty(RefEl) // no AddRef
|
||||||
@ -8168,7 +8168,7 @@ begin
|
|||||||
ReadElType(Obj,'Members',El,@Set_Variant_Members,aContext);
|
ReadElType(Obj,'Members',El,@Set_Variant_Members,aContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPCUReader.ReadRecordScope(Obj: TJSONObject; Scope: TPasRecordScope;
|
procedure TPCUReader.ReadRecordScope(Obj: TJSONObject; Scope: TPas2jsRecordScope;
|
||||||
aContext: TPCUReaderContext);
|
aContext: TPCUReaderContext);
|
||||||
begin
|
begin
|
||||||
ReadElementReference(Obj,Scope,'DefaultProperty',@Set_RecordScope_DefaultProperty);
|
ReadElementReference(Obj,Scope,'DefaultProperty',@Set_RecordScope_DefaultProperty);
|
||||||
@ -8180,13 +8180,13 @@ procedure TPCUReader.ReadRecordType(Obj: TJSONObject; El: TPasRecordType;
|
|||||||
var
|
var
|
||||||
Data: TJSONData;
|
Data: TJSONData;
|
||||||
Id: Integer;
|
Id: Integer;
|
||||||
Scope: TPasRecordScope;
|
Scope: TPas2jsRecordScope;
|
||||||
SubObj: TJSONObject;
|
SubObj: TJSONObject;
|
||||||
begin
|
begin
|
||||||
if FileVersion<3 then
|
if FileVersion<3 then
|
||||||
RaiseMsg(20190109214718,El,'record format changed');
|
RaiseMsg(20190109214718,El,'record format changed');
|
||||||
|
|
||||||
Scope:=TPasRecordScope(Resolver.CreateScope(El,TPasRecordScope));
|
Scope:=TPas2jsRecordScope(Resolver.CreateScope(El,TPas2jsRecordScope));
|
||||||
El.CustomData:=Scope;
|
El.CustomData:=Scope;
|
||||||
|
|
||||||
ReadPasElement(Obj,El,aContext);
|
ReadPasElement(Obj,El,aContext);
|
||||||
|
@ -75,7 +75,7 @@ type
|
|||||||
procedure CheckRestoredSectionScope(const Path: string; Orig, Rest: TPas2JSSectionScope; Flags: TPCCheckFlags); virtual;
|
procedure CheckRestoredSectionScope(const Path: string; Orig, Rest: TPas2JSSectionScope; Flags: TPCCheckFlags); virtual;
|
||||||
procedure CheckRestoredInitialFinalizationScope(const Path: string; Orig, Rest: TPas2JSInitialFinalizationScope; Flags: TPCCheckFlags); virtual;
|
procedure CheckRestoredInitialFinalizationScope(const Path: string; Orig, Rest: TPas2JSInitialFinalizationScope; Flags: TPCCheckFlags); virtual;
|
||||||
procedure CheckRestoredEnumTypeScope(const Path: string; Orig, Rest: TPasEnumTypeScope; Flags: TPCCheckFlags); virtual;
|
procedure CheckRestoredEnumTypeScope(const Path: string; Orig, Rest: TPasEnumTypeScope; Flags: TPCCheckFlags); virtual;
|
||||||
procedure CheckRestoredRecordScope(const Path: string; Orig, Rest: TPasRecordScope; Flags: TPCCheckFlags); virtual;
|
procedure CheckRestoredRecordScope(const Path: string; Orig, Rest: TPas2jsRecordScope; Flags: TPCCheckFlags); virtual;
|
||||||
procedure CheckRestoredClassScope(const Path: string; Orig, Rest: TPas2JSClassScope; Flags: TPCCheckFlags); virtual;
|
procedure CheckRestoredClassScope(const Path: string; Orig, Rest: TPas2JSClassScope; Flags: TPCCheckFlags); virtual;
|
||||||
procedure CheckRestoredProcScope(const Path: string; Orig, Rest: TPas2JSProcedureScope; Flags: TPCCheckFlags); virtual;
|
procedure CheckRestoredProcScope(const Path: string; Orig, Rest: TPas2JSProcedureScope; Flags: TPCCheckFlags); virtual;
|
||||||
procedure CheckRestoredScopeRefs(const Path: string; Orig, Rest: TPasScopeReferences; Flags: TPCCheckFlags); virtual;
|
procedure CheckRestoredScopeRefs(const Path: string; Orig, Rest: TPasScopeReferences; Flags: TPCCheckFlags); virtual;
|
||||||
@ -805,7 +805,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomTestPrecompile.CheckRestoredRecordScope(const Path: string;
|
procedure TCustomTestPrecompile.CheckRestoredRecordScope(const Path: string;
|
||||||
Orig, Rest: TPasRecordScope; Flags: TPCCheckFlags);
|
Orig, Rest: TPas2jsRecordScope; Flags: TPCCheckFlags);
|
||||||
begin
|
begin
|
||||||
CheckRestoredReference(Path+'.DefaultProperty',Orig.DefaultProperty,Rest.DefaultProperty);
|
CheckRestoredReference(Path+'.DefaultProperty',Orig.DefaultProperty,Rest.DefaultProperty);
|
||||||
CheckRestoredIdentifierScope(Path,Orig,Rest,Flags);
|
CheckRestoredIdentifierScope(Path,Orig,Rest,Flags);
|
||||||
@ -1107,8 +1107,8 @@ begin
|
|||||||
CheckRestoredInitialFinalizationScope(Path+'[TPas2JSInitialFinalizationScope]',TPas2JSInitialFinalizationScope(Orig),TPas2JSInitialFinalizationScope(Rest),Flags)
|
CheckRestoredInitialFinalizationScope(Path+'[TPas2JSInitialFinalizationScope]',TPas2JSInitialFinalizationScope(Orig),TPas2JSInitialFinalizationScope(Rest),Flags)
|
||||||
else if C=TPasEnumTypeScope then
|
else if C=TPasEnumTypeScope then
|
||||||
CheckRestoredEnumTypeScope(Path+'[TPasEnumTypeScope]',TPasEnumTypeScope(Orig),TPasEnumTypeScope(Rest),Flags)
|
CheckRestoredEnumTypeScope(Path+'[TPasEnumTypeScope]',TPasEnumTypeScope(Orig),TPasEnumTypeScope(Rest),Flags)
|
||||||
else if C=TPasRecordScope then
|
else if C=TPas2jsRecordScope then
|
||||||
CheckRestoredRecordScope(Path+'[TPasRecordScope]',TPasRecordScope(Orig),TPasRecordScope(Rest),Flags)
|
CheckRestoredRecordScope(Path+'[TPas2jsRecordScope]',TPas2jsRecordScope(Orig),TPas2jsRecordScope(Rest),Flags)
|
||||||
else if C=TPas2JSClassScope then
|
else if C=TPas2JSClassScope then
|
||||||
CheckRestoredClassScope(Path+'[TPas2JSClassScope]',TPas2JSClassScope(Orig),TPas2JSClassScope(Rest),Flags)
|
CheckRestoredClassScope(Path+'[TPas2JSClassScope]',TPas2JSClassScope(Orig),TPas2JSClassScope(Rest),Flags)
|
||||||
else if C=TPas2JSProcedureScope then
|
else if C=TPas2JSProcedureScope then
|
||||||
|
@ -33,10 +33,10 @@ type
|
|||||||
//Procedure TestGen_Class_ClassProc_Delphi;
|
//Procedure TestGen_Class_ClassProc_Delphi;
|
||||||
//Procedure TestGen_Class_ReferGenClass_DelphiFail;
|
//Procedure TestGen_Class_ReferGenClass_DelphiFail;
|
||||||
Procedure TestGen_Class_ClassConstructor;
|
Procedure TestGen_Class_ClassConstructor;
|
||||||
// ToDo: rename local const T
|
|
||||||
Procedure TestGen_Class_TypeCastSpecializesWarn;
|
Procedure TestGen_Class_TypeCastSpecializesWarn;
|
||||||
Procedure TestGen_Class_TypeCastSpecializesJSValueNoWarn;
|
Procedure TestGen_Class_TypeCastSpecializesJSValueNoWarn;
|
||||||
procedure TestGen_Class_VarArgsOfType;
|
procedure TestGen_Class_VarArgsOfType;
|
||||||
|
procedure TestGen_Class_OverloadsInUnit;
|
||||||
|
|
||||||
// generic external class
|
// generic external class
|
||||||
procedure TestGen_ExtClass_Array;
|
procedure TestGen_ExtClass_Array;
|
||||||
@ -772,6 +772,84 @@ begin
|
|||||||
'']));
|
'']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestGenerics.TestGen_Class_OverloadsInUnit;
|
||||||
|
begin
|
||||||
|
StartProgram(true,[supTObject]);
|
||||||
|
AddModuleWithIntfImplSrc('UnitA.pas',
|
||||||
|
LinesToStr([
|
||||||
|
'type',
|
||||||
|
' generic TBird<T> = class',
|
||||||
|
' const c = 13;',
|
||||||
|
' constructor Create(w: T);',
|
||||||
|
' constructor Create(b: boolean);',
|
||||||
|
' end;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'constructor TBird.Create(w: T);',
|
||||||
|
'const c = 14;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'constructor TBird.Create(b: boolean);',
|
||||||
|
'const c = 15;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'']));
|
||||||
|
Add([
|
||||||
|
'uses UnitA;',
|
||||||
|
'type',
|
||||||
|
' TWordBird = specialize TBird<word>;',
|
||||||
|
' TDoubleBird = specialize TBird<double>;',
|
||||||
|
'var',
|
||||||
|
' wb: TWordBird;',
|
||||||
|
' db: TDoubleBird;',
|
||||||
|
'begin',
|
||||||
|
' wb:=TWordBird.Create(3);',
|
||||||
|
' wb:=TWordBird.Create(true);',
|
||||||
|
' db:=TDoubleBird.Create(1.3);',
|
||||||
|
' db:=TDoubleBird.Create(true);',
|
||||||
|
'']);
|
||||||
|
ConvertProgram;
|
||||||
|
CheckUnit('UnitA.pas',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
'rtl.module("UnitA", ["system"], function () {',
|
||||||
|
' var $mod = this;',
|
||||||
|
' rtl.createClass($mod, "TBird$G1", pas.system.TObject, function () {',
|
||||||
|
' this.c = 13;',
|
||||||
|
' var c$1 = 14;',
|
||||||
|
' this.Create$1 = function (w) {',
|
||||||
|
' return this;',
|
||||||
|
' };',
|
||||||
|
' var c$2 = 15;',
|
||||||
|
' this.Create$2 = function (b) {',
|
||||||
|
' return this;',
|
||||||
|
' };',
|
||||||
|
' });',
|
||||||
|
' rtl.createClass($mod, "TBird$G2", pas.system.TObject, function () {',
|
||||||
|
' this.c = 13;',
|
||||||
|
' var c$1 = 14;',
|
||||||
|
' this.Create$1 = function (w) {',
|
||||||
|
' return this;',
|
||||||
|
' };',
|
||||||
|
' var c$2 = 15;',
|
||||||
|
' this.Create$2 = function (b) {',
|
||||||
|
' return this;',
|
||||||
|
' };',
|
||||||
|
' });',
|
||||||
|
'});',
|
||||||
|
'']));
|
||||||
|
CheckSource('TestGen_Class_OverloadsInUnit',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
'this.wb = null;',
|
||||||
|
'this.db = null;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([ // $mod.$main
|
||||||
|
'$mod.wb = pas.UnitA.TBird$G1.$create("Create$1", [3]);',
|
||||||
|
'$mod.wb = pas.UnitA.TBird$G1.$create("Create$2", [true]);',
|
||||||
|
'$mod.db = pas.UnitA.TBird$G2.$create("Create$1", [1.3]);',
|
||||||
|
'$mod.db = pas.UnitA.TBird$G2.$create("Create$2", [true]);',
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestGenerics.TestGen_ExtClass_Array;
|
procedure TTestGenerics.TestGen_ExtClass_Array;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user