Browse Source

pastojs: ShortRefGlobals: local var for TEnumType

git-svn-id: trunk@46959 -
Mattias Gaertner 4 years ago
parent
commit
ffef243908
2 changed files with 113 additions and 5 deletions
  1. 38 5
      packages/pastojs/src/fppas2js.pp
  2. 75 0
      packages/pastojs/tests/tcoptimizations.pas

+ 38 - 5
packages/pastojs/src/fppas2js.pp

@@ -15278,6 +15278,8 @@ function TPasToJSConverter.ConvertEnumType(El: TPasEnumType;
 //     minvalue: 0,
 //     maxvalue: 1
 //   });
+//  coShortRefGlobals:
+//  var $lt = this.TMyEnum ...
 var
   ObjectContect: TObjectContext;
   i: Integer;
@@ -15285,7 +15287,7 @@ var
   ParentObj, Obj, TIObj: TJSObjectLiteral;
   ObjLit, TIProp: TJSObjectLiteralElement;
   AssignSt: TJSSimpleAssignStatement;
-  JSName: TJSString;
+  JSName: string;
   Call: TJSCallExpression;
   List: TJSStatementList;
   ok: Boolean;
@@ -15293,6 +15295,7 @@ var
   Src: TJSSourceElements;
   ProcScope: TPas2JSProcedureScope;
   VarSt: TJSVariableStatement;
+  GlobalCtx: TConvertContext;
 begin
   Result:=nil;
   for i:=0 to El.Values.Count-1 do
@@ -15322,11 +15325,14 @@ begin
     else if El.Parent is TProcedureBody then
       begin
       // add 'var TypeName = {}'
-      VarSt:=CreateVarStatement(TransformElToJSName(El,AContext),Obj,El);
+      JSName:=TransformElToJSName(El,AContext);
+      VarSt:=CreateVarStatement(JSName,Obj,El);
       if AContext.JSElement is TJSSourceElements then
         begin
         Src:=TJSSourceElements(AContext.JSElement);
         AddToSourceElements(Src,VarSt); // keep Result=nil
+        if AContext is TFunctionContext then
+          TFunctionContext(AContext).AddLocalVar(JSName,El,cvkGlobal,false);
         end
       else
         Result:=VarSt;
@@ -15338,20 +15344,47 @@ begin
       AssignSt.LHS:=CreateSubDeclNameExpr(El,AContext);
       AssignSt.Expr:=Obj;
       Result:=AssignSt;
+      if (coShortRefGlobals in Options) and (AContext is TFunctionContext) then
+        begin
+        GlobalCtx:=AContext;
+        while (GlobalCtx.PasElement is TPasMembersType) do
+          GlobalCtx:=GlobalCtx.Parent;
+        if (GlobalCtx<>AContext) and (GlobalCtx is TFunctionContext) then
+          begin
+          // add to GlobalCtx:      var $lt = {}
+          // add to local context:  this.TypeName = $lt
+          if not (GlobalCtx.JSElement is TJSSourceElements) then
+            RaiseNotSupported(El,AContext,20200926181516,GetObjName(GlobalCtx.JSElement));
+          Src:=TJSSourceElements(GlobalCtx.JSElement);
+          JSName:=TFunctionContext(AContext).CreateLocalIdentifier(GetBIName(pbivnLocalTypeRef));
+          AssignSt.Expr:=CreatePrimitiveDotExpr(JSName,El);
+
+          VarSt:=CreateVarStatement(JSName,Obj,El);
+          AddToSourceElements(Src,VarSt);
+          TFunctionContext(GlobalCtx).AddLocalVar(JSName,El,cvkGlobal,false);
+          end
+        else
+          begin
+          // var $lt = this.TypeName = {}
+          JSName:=TFunctionContext(AContext).CreateLocalIdentifier(GetBIName(pbivnLocalTypeRef));
+          TFunctionContext(AContext).AddLocalVar(JSName,El,cvkGlobal,false);
+          Result:=CreateVarStatement(JSName,AssignSt,El);
+          end;
+        end;
       end;
 
     ObjectContect:=TObjectContext.Create(El,Obj,AContext);
     for i:=0 to El.Values.Count-1 do
       begin
       EnumValue:=TPasEnumValue(El.Values[i]);
-      JSName:=TJSString(TransformElToJSName(EnumValue,AContext));
+      JSName:=TransformElToJSName(EnumValue,AContext);
       // add "0":"value"
       ObjLit:=Obj.Elements.AddElement;
       ObjLit.Name:=TJSString(IntToStr(i));
-      ObjLit.Expr:=CreateLiteralJSString(El,JSName);
+      ObjLit.Expr:=CreateLiteralJSString(El,TJSString(JSName));
       // add value:0
       ObjLit:=Obj.Elements.AddElement;
-      ObjLit.Name:=JSName;
+      ObjLit.Name:=TJSString(JSName);
       ObjLit.Expr:=CreateLiteralNumber(El,i);
       end;
 

+ 75 - 0
packages/pastojs/tests/tcoptimizations.pas

@@ -61,6 +61,7 @@ type
     procedure TestOptShortRefGlobals_Unit_FromIntfImpl_ToIntfImpl;
     procedure TestOptShortRefGlobals_Property;
     procedure TestOptShortRefGlobals_GenericFunction;
+    procedure TestOptShortRefGlobals_SameUnit_EnumType;
 
     // Whole Program Optimization
     procedure TestWPO_OmitLocalVar;
@@ -490,6 +491,80 @@ begin
     '']));
 end;
 
+procedure TTestOptimizations.TestOptShortRefGlobals_SameUnit_EnumType;
+begin
+  StartUnit(true,[supTObject]);
+  Add([
+  '{$optimization JSShortRefGlobals}',
+  'interface',
+  'type',
+  '  TEnum = (red,blue);',
+  '  TBird = class',
+  '  type',
+  '    TFlag = (big,small);',
+  '    procedure Fly;',
+  '  end;',
+  'var f: TBird.TFlag;',
+  'procedure Run;',
+  'implementation',
+  'procedure TBird.Fly;',
+  'begin',
+  '  f:=small;',
+  'end;',
+  'procedure Run;',
+  'type TSub = (left,right);',
+  'var e: TEnum;',
+  '  s: TSub;',
+  'begin',
+  '  e:=red;',
+  '  s:=right;',
+  '  f:=big;',
+  'end;',
+  '']);
+  ConvertUnit;
+  CheckSource('TestOptShortRefGlobals_SameUnit_EnumType',
+    LinesToStr([
+    'var $lm = pas.system;',
+    'var $lt1 = $lm.TObject;',
+    'var $lt = this.TEnum = {',
+    '  "0": "red",',
+    '  red: 0,',
+    '  "1": "blue",',
+    '  blue: 1',
+    '};',
+    'var $lt2 = {',
+    '    "0": "big",',
+    '    big: 0,',
+    '    "1": "small",',
+    '    small: 1',
+    '  };',
+    'rtl.createClass(this, "TBird", $lt1, function () {',
+    '  this.TFlag = $lt2;',
+    '  this.Fly = function () {',
+    '    $mod.f = $lt2.small;',
+    '  };',
+    '});',
+    'this.f = 0;',
+    'var TSub = {',
+    '  "0": "left",',
+    '  left: 0,',
+    '  "1": "right",',
+    '  right: 1',
+    '};',
+    'this.Run = function () {',
+    '  var e = 0;',
+    '  var s = 0;',
+    '  e = $lt.red;',
+    '  s = TSub.right;',
+    '  $mod.f = $lt2.big;',
+    '};',
+    '']),
+    LinesToStr([
+    '']),
+    LinesToStr([
+    '']));
+end;
+
 procedure TTestOptimizations.TestWPO_OmitLocalVar;
 begin
   StartProgram(false);