pastojs: rename unit implementation const

git-svn-id: trunk@44146 -
This commit is contained in:
Mattias Gaertner 2020-02-10 16:42:58 +00:00
parent 40a6059143
commit b1900bae9e
2 changed files with 136 additions and 15 deletions

View File

@ -2929,6 +2929,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 not HasOverloadIndex(El,true) then exit; if not HasOverloadIndex(El,true) then exit;
ThisChanged:=false; ThisChanged:=false;
@ -2949,6 +2950,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 ElevatedLocals<>nil then if ElevatedLocals<>nil then
begin begin
Identifier:=ElevatedLocals.Find(El.Name); Identifier:=ElevatedLocals.Find(El.Name);
@ -3060,6 +3062,7 @@ var
begin begin
// => count overloads in this section // => count overloads in this section
OverloadIndex:=GetOverloadIndex(El); OverloadIndex:=GetOverloadIndex(El);
//if SameText(El.Name,'ci') then writeln('TPas2JSResolver.RenameOverload ',GetObjPath(El),' ',OverloadIndex);
if OverloadIndex=0 then if OverloadIndex=0 then
exit(false); // there is no overload exit(false); // there is no overload
@ -3185,16 +3188,51 @@ 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: TPasProcedure; Proc, ImplProc: TPasProcedure;
ProcScope: TPasProcedureScope; ProcScope, ImplProcScope: TPas2JSProcedureScope;
ClassScope, aScope: TPasClassScope; ClassScope, aScope: TPasClassScope;
ClassEl: TPasClassType; 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]);
@ -3202,26 +3240,49 @@ begin
if C.InheritsFrom(TPasProcedure) then if C.InheritsFrom(TPasProcedure) then
begin begin
Proc:=TPasProcedure(El); Proc:=TPasProcedure(El);
ProcScope:=Proc.CustomData as TPasProcedureScope; 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 if ProcScope.DeclarationProc<>nil then
continue;
if ProcScope.ImplProc<>nil then
begin begin
Proc:=ProcScope.ImplProc; // ImplProc with separate declaration
ProcScope:=TPasProcedureScope(Proc.CustomData); 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;
if ImplProc<>nil then
ImplProcScope:=TPas2JSProcedureScope(ImplProc.CustomData)
else
begin
ImplProc:=Proc;
ImplProcScope:=ProcScope;
end; end;
{$IFDEF VerbosePas2JS} {$IFDEF VerbosePas2JS}
//writeln('TPas2JSResolver.RenameSubOverloads Proc=',Proc.Name,' DeclarationProc=',GetObjName(ProcScope.DeclarationProc),' ImplProc=',GetObjName(ProcScope.ImplProc),' ClassScope=',GetObjName(ProcScope.ClassOrRecordScope)); //writeln('TPas2JSResolver.RenameSubOverloads ImplProc=',ImplProc.Name,' DeclarationProc=',GetObjName(ProcScope.DeclarationProc),' ClassScope=',GetObjName(ImplProcScope.ClassOrRecordScope));
{$ENDIF} {$ENDIF}
ProcBody:=Proc.Body; ProcBody:=ImplProc.Body;
if ProcBody<>nil then if ProcBody<>nil then
begin begin
PushOverloadScope(ProcScope); OldScopeCount:=FOverloadScopes.Count;
if (ImplProcScope.ClassRecScope<>nil)
and not (Proc.Parent is TPasMembersType) then
begin
// push class scopes
LocalPushClassOrRecScopes(ImplProcScope.ClassRecScope);
end;
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);
end; end;
end end
else if (C=TPasClassType) or (C=TPasRecordType) then else if (C=TPasClassType) or (C=TPasRecordType) then
@ -3253,8 +3314,7 @@ begin
RenameSubOverloads(TPasMembersType(El).Members); RenameSubOverloads(TPasMembersType(El).Members);
// restore scope // restore scope
while FOverloadScopes.Count>OldScopeCount do RestoreScopeLvl(OldScopeCount);
PopOverloadScope;
end; end;
end; end;
{$IFDEF VerbosePas2JS} {$IFDEF VerbosePas2JS}

View File

@ -529,7 +529,8 @@ type
Procedure TestClass_ExternalOverrideFail; Procedure TestClass_ExternalOverrideFail;
Procedure TestClass_ExternalVar; Procedure TestClass_ExternalVar;
Procedure TestClass_Const; Procedure TestClass_Const;
Procedure TestClass_LocalConstDuplicate; Procedure TestClass_LocalConstDuplicate_Prg;
Procedure TestClass_LocalConstDuplicate_Unit;
// ToDo: Procedure TestAdvRecord_LocalConstDuplicate; // ToDo: Procedure TestAdvRecord_LocalConstDuplicate;
Procedure TestClass_LocalVarSelfFail; Procedure TestClass_LocalVarSelfFail;
Procedure TestClass_ArgSelfFail; Procedure TestClass_ArgSelfFail;
@ -14248,7 +14249,7 @@ begin
''])); '']));
end; end;
procedure TTestModule.TestClass_LocalConstDuplicate; procedure TTestModule.TestClass_LocalConstDuplicate_Prg;
begin begin
StartProgram(false); StartProgram(false);
Add([ Add([
@ -14279,7 +14280,7 @@ begin
'begin', 'begin',
'']); '']);
ConvertProgram; ConvertProgram;
CheckSource('TestClass_LocalConstDuplicate', CheckSource('TestClass_LocalConstDuplicate_Prg',
LinesToStr([ LinesToStr([
'rtl.createClass($mod, "TObject", null, function () {', 'rtl.createClass($mod, "TObject", null, function () {',
' this.cI = 3;', ' this.cI = 3;',
@ -14307,6 +14308,66 @@ begin
''])); '']));
end; end;
procedure TTestModule.TestClass_LocalConstDuplicate_Unit;
begin
StartUnit(false);
Add([
'interface',
'type',
' TObject = class',
' const cI: longint = 3;',
' procedure Fly;',
' procedure Run;',
' end;',
' TBird = class',
' procedure Go;',
' end;',
'implementation',
'procedure tobject.fly;',
'const cI: word = 4;',
'begin',
' if cI=Self.cI then ;',
'end;',
'procedure tobject.run;',
'const cI: word = 5;',
'begin',
' if cI=Self.cI then ;',
'end;',
'procedure tbird.go;',
'const cI: word = 6;',
'begin',
' if cI=Self.cI then ;',
'end;',
'']);
ConvertUnit;
CheckSource('TestClass_LocalConstDuplicate_Unit',
LinesToStr([
'rtl.createClass($mod, "TObject", null, function () {',
' this.cI = 3;',
' this.$init = function () {',
' };',
' this.$final = function () {',
' };',
' var cI$1 = 4;',
' this.Fly = function () {',
' if (cI$1 === this.cI) ;',
' };',
' var cI$2 = 5;',
' this.Run = function () {',
' if (cI$2 === this.cI) ;',
' };',
'});',
'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
' var cI$3 = 6;',
' this.Go = function () {',
' if (cI$3 === this.cI) ;',
' };',
'});',
'']),
'',
'');
end;
procedure TTestModule.TestClass_LocalVarSelfFail; procedure TTestModule.TestClass_LocalVarSelfFail;
begin begin
StartProgram(false); StartProgram(false);