summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattias <mattias@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-04-26 20:08:13 +0000
committermattias <mattias@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-04-26 20:08:13 +0000
commit8629490cd66002fb627a5ae14e8f6f652e8df4cd (patch)
treef55bc469196fb7f04e5814b814838f496512f5d2
parent5632f39a7cf6128864d4b177dcf2efd12172356a (diff)
downloadfpc-8629490cd66002fb627a5ae14e8f6f652e8df4cd.tar.gz
pas2js: fixed type helper nested procedure Self
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@45123 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--packages/pastojs/src/fppas2js.pp43
-rw-r--r--packages/pastojs/tests/tcmodules.pas39
2 files changed, 59 insertions, 23 deletions
diff --git a/packages/pastojs/src/fppas2js.pp b/packages/pastojs/src/fppas2js.pp
index d8410b96c7..2d319662b9 100644
--- a/packages/pastojs/src/fppas2js.pp
+++ b/packages/pastojs/src/fppas2js.pp
@@ -15106,42 +15106,39 @@ begin
ClassPath:=CreateReferencePath(ProcScope.ClassRecScope.Element,AContext,rpkPathAndName);
Call.AddArg(CreatePrimitiveDotExpr(ClassPath,PosEl));
end;
- if (ImplProc.Body.Functions.Count>0)
- or aResolver.HasAnonymousFunctions(ImplProc.Body.Body) then
- begin
- // has nested procs -> add "var self = this;"
- FuncContext.AddLocalVar(GetBIName(pbivnSelf),ThisPas);
- SelfSt:=CreateVarStatement(GetBIName(pbivnSelf),
- CreatePrimitiveDotExpr('this',ImplProc),ImplProc);
- AddBodyStatement(SelfSt,PosEl);
- if ImplProcScope.SelfArg<>nil then
- begin
- // redirect Pascal-Self to JS-Self
- FuncContext.AddLocalVar(GetBIName(pbivnSelf),ImplProcScope.SelfArg);
- end;
- end
- else if ImplProcScope.SelfArg<>nil then
- begin
- // no nested procs -> redirect Pascal-Self to JS-this
- FuncContext.AddLocalVar('this',ImplProcScope.SelfArg);
- end;
end
else
begin
- // no "this"
+ // "this" has no direct Pascal element
if ProcScope.ClassRecScope<>nil then
begin
- // static method -> hide local
+ // static method
ClassOrRec:=ProcScope.ClassRecScope.Element;
LocalVar:=FuncContext.FindLocalIdentifier(ClassOrRec);
if (LocalVar<>nil) and (LocalVar.Name='this') then
+ // "this" is not the class -> hide it (absolute path will be used)
FuncContext.AddLocalVar(LocalVarHide,ClassOrRec);
end;
+ end;
+ if (ImplProc.Body.Functions.Count>0)
+ or aResolver.HasAnonymousFunctions(ImplProc.Body.Body) then
+ begin
+ // has nested procs -> add "var $Self = this;"
+ if ThisPas<>nil then
+ FuncContext.AddLocalVar(GetBIName(pbivnSelf),ThisPas);
+ SelfSt:=CreateVarStatement(GetBIName(pbivnSelf),
+ CreatePrimitiveDotExpr('this',ImplProc),ImplProc);
+ AddBodyStatement(SelfSt,PosEl);
if ImplProcScope.SelfArg<>nil then
begin
- // no nested procs -> redirect Pascal-Self to JS-this
- FuncContext.AddLocalVar('this',ImplProcScope.SelfArg);
+ // redirect Pascal-Self to JS-Self
+ FuncContext.AddLocalVar(GetBIName(pbivnSelf),ImplProcScope.SelfArg);
end;
+ end
+ else if ImplProcScope.SelfArg<>nil then
+ begin
+ // no nested procs -> redirect Pascal-Self to JS-this
+ FuncContext.AddLocalVar('this',ImplProcScope.SelfArg);
end;
end;
{$IFDEF VerbosePas2JS}
diff --git a/packages/pastojs/tests/tcmodules.pas b/packages/pastojs/tests/tcmodules.pas
index b8aec665fa..3ee8dbd111 100644
--- a/packages/pastojs/tests/tcmodules.pas
+++ b/packages/pastojs/tests/tcmodules.pas
@@ -709,6 +709,7 @@ type
Procedure TestTypeHelper_EnumType;
Procedure TestTypeHelper_SetType;
Procedure TestTypeHelper_InterfaceType;
+ Procedure TestTypeHelper_NestedSelf;
// proc types
Procedure TestProcType;
@@ -24691,6 +24692,44 @@ begin
'']));
end;
+procedure TTestModule.TestTypeHelper_NestedSelf;
+begin
+ StartProgram(false);
+ Add([
+ '{$modeswitch typehelpers}',
+ 'type',
+ ' THelper = type helper for string',
+ ' procedure Run(Value: string);',
+ ' end;',
+ 'procedure THelper.Run(Value: string);',
+ ' function Sub(i: nativeint): boolean;',
+ ' begin',
+ ' Result:=Self[i+1]=Value[i];',
+ ' end;',
+ 'begin',
+ ' if Self[3]=Value[4] then ;',
+ 'end;',
+ 'begin',
+ '']);
+ ConvertProgram;
+ CheckSource('TestTypeHelper_NestedSelf',
+ LinesToStr([ // statements
+ 'rtl.createHelper($mod, "THelper", null, function () {',
+ ' this.Run = function (Value) {',
+ ' var $Self = this;',
+ ' function Sub(i) {',
+ ' var Result = false;',
+ ' Result = $Self.get().charAt((i + 1) - 1) === Value.charAt(i - 1);',
+ ' return Result;',
+ ' };',
+ ' if ($Self.get().charAt(2) === Value.charAt(3)) ;',
+ ' };',
+ '});',
+ '']),
+ LinesToStr([ // $mod.$main
+ '']));
+end;
+
procedure TTestModule.TestProcType;
begin
StartProgram(false);