瀏覽代碼

pastojs: optimization ShortRefGlobals

git-svn-id: trunk@46927 -
Mattias Gaertner 4 年之前
父節點
當前提交
755773caad

文件差異過大導致無法顯示
+ 355 - 265
packages/pastojs/src/fppas2js.pp


+ 59 - 49
packages/pastojs/src/pas2jscompiler.pp

@@ -38,6 +38,7 @@ uses
   Classes, SysUtils, contnrs,
   jsbase, jstree, jswriter, JSSrcMap, fpjson,
   PScanner, PParser, PasTree, PasResolver, PasResolveEval, PasUseAnalyzer,
+  Pas2JSUtils,
   pas2jsresstrfile, pas2jsresources, pas2jshtmlresources, pas2jsjsresources,
   FPPas2Js, FPPJsSrcMap, Pas2jsLogger, Pas2jsFS, Pas2jsPParser, Pas2jsUseAnalyzer;
 
@@ -96,6 +97,7 @@ const
   nPostProcessorFinished = 143; sPostProcessorFinished = 'Post processor finished';
   nRTLIdentifierChanged = 144; sRTLIdentifierChanged = 'RTL identifier %s changed from %s to %s';
   nSkipNoConstResourcestring = 145; sSkipNoConstResourcestring = 'Resource string %s is not a constant, not adding to resourcestrings file.';
+  nUnknownOptimizationOption = 146; sUnknownOptimizationOption = 'unknown -Oo option %s';
   // Note: error numbers 201+ are used by Pas2jsFileCache
 
 //------------------------------------------------------------------------------
@@ -133,9 +135,10 @@ type
     coWriteMsgToStdErr,
     coPrecompile, // create precompile file
     // optimizations
-    coEnumValuesAsNumbers,
-    coKeepNotUsedPrivates,
-    coKeepNotUsedDeclarationsWPO,
+    coEnumValuesAsNumbers, // -O1
+    coKeepNotUsedPrivates, // -O-
+    coKeepNotUsedDeclarationsWPO, // -O-
+    coShortRefGlobals, // -O2
     // source map
     coSourceMapCreate,
     coSourceMapInclude,
@@ -160,9 +163,10 @@ const
   DefaultResourceMode = rmHTML;
 
   coShowAll = [coShowErrors..coShowDebug];
-  coO1Enable = [coEnumValuesAsNumbers];
-  coO1Disable = [coKeepNotUsedPrivates,coKeepNotUsedDeclarationsWPO];
-
+  coAllOptimizations = [coEnumValuesAsNumbers..coShortRefGlobals];
+  coO0 = [coKeepNotUsedPrivates,coKeepNotUsedDeclarationsWPO];
+  coO1 = [coEnumValuesAsNumbers];
+  coO2 = coO1+[coShortRefGlobals];
 
   p2jscoCaption: array[TP2jsCompilerOption] of string = (
     // only used by experts or programs parsing the pas2js output, no need for resourcestrings
@@ -195,6 +199,7 @@ const
     'Enum values as numbers',
     'Keep not used private declarations',
     'Keep not used declarations (WPO)',
+    'Create short local variables for globals',
     'Create source map',
     'Include Pascal sources in source map',
     'Do not shorten filenames in source map',
@@ -532,7 +537,6 @@ type
     function GetTargetProcessor: TPasToJsProcessor;
     function GetWriteDebugLog: boolean;
     function GetWriteMsgToStdErr: boolean;
-    function HandleOptionOptimization(C: Char; aValue: String): Boolean;
     function IndexOfInsertJSFilename(const aFilename: string): integer;
     procedure InsertCustomJSFiles(aWriter: TPas2JSMapper);
     function LoadUsedUnit(Info: TLoadUnitInfo; Context: TPas2jsCompilerFile): TPas2jsCompilerFile;
@@ -607,6 +611,7 @@ type
     function HandleOptionM(aValue: String; Quick: Boolean): Boolean; virtual;
     procedure HandleOptionConfigFile(aPos: Integer; const aFileName: string); virtual;
     procedure HandleOptionInfo(aValue: string);
+    function HandleOptionOptimization(C: Char; aValue: String): Boolean;
     // DoWriteJSFile: return false to use the default write function.
     function DoWriteJSFile(const DestFilename: String; aWriter: TPas2JSMapper): Boolean; virtual;
     procedure Compile(StartTime: TDateTime);
@@ -730,9 +735,9 @@ function GetCompiledTargetOS: string;
 function GetCompiledTargetCPU: string;
 
 implementation
-// !! No filesystem units here.
 
-uses pas2jsutils;
+// !! No filesystem units here.
+//uses ;
 
 
 function GetCompiledDate: string;
@@ -1048,6 +1053,8 @@ begin
 
   if coEnumValuesAsNumbers in Compiler.Options then
     Include(Result,fppas2js.coEnumNumbers);
+  if coShortRefGlobals in Compiler.Options then
+    Include(Result,fppas2js.coShortRefGlobals);
 
   if coLowerCase in Compiler.Options then
     Include(Result,fppas2js.coLowerCase)
@@ -3292,6 +3299,8 @@ begin
   r(mtWarning,nPostProcessorWarnX,sPostProcessorWarnX);
   r(mtInfo,nPostProcessorFinished,sPostProcessorFinished);
   r(mtInfo,nRTLIdentifierChanged,sRTLIdentifierChanged);
+  r(mtNote,nSkipNoConstResourcestring,sSkipNoConstResourcestring);
+  r(mtWarning,nUnknownOptimizationOption,sUnknownOptimizationOption);
   Pas2jsPParser.RegisterMessages(Log);
 end;
 
@@ -3353,39 +3362,6 @@ begin
   end;
 end;
 
-function TPas2jsCompiler.HandleOptionOptimization(C: Char; aValue: String): Boolean;
-Var
-  Enable: Boolean;
-begin
-  Result:=True;
-  case C of
-  '-': Options:=Options-coO1Enable+coO1Disable;
-  '1': Options:=Options+coO1Enable-coO1Disable;
-  'o':
-    begin
-    if aValue='' then
-      ParamFatal('missing -Oo option');
-    Enable:=true;
-    c:=aValue[length(aValue)];
-    if c in ['+','-'] then
-    begin
-      Enable:=c='+';
-      Delete(aValue,length(aValue),1);
-    end;
-    Case LowerCase(avalue) of
-     'enumnumbers': SetOption(coEnumValuesAsNumbers,Enable);
-     'emovenotusedprivates': SetOption(coKeepNotUsedPrivates,not Enable);
-     'removenotuseddeclarations': SetOption(coKeepNotUsedDeclarationsWPO,not Enable)
-    else
-      Result:=False;
-    end;
-    end;
-  else
-    Result:=False;
-  end;
-
-end;
-
 function TPas2jsCompiler.HandleOptionJ(C: Char; aValue: String;
   Quick, FromCmdLine: Boolean): Boolean;
 
@@ -3636,10 +3612,8 @@ begin
 end;
 
 procedure TPas2jsCompiler.HandleOptionConfigFile(aPos: Integer; const aFileName: string);
-
 Var
   FN: String;
-
 begin
   // load extra config file
   if aFilename='' then
@@ -3651,7 +3625,6 @@ begin
 end;
 
 procedure TPas2jsCompiler.HandleOptionInfo(aValue: string);
-
 Var
   InfoMsg: String;
 
@@ -3727,9 +3700,9 @@ begin
         Log.LogPlain(PasToJsProcessorNames[pr]);
     'm':
       begin
-      // write list of supported modeswitches
-      for ms in (msAllPas2jsModeSwitches-AllLanguageModes) do
-        Log.LogPlain(SModeSwitchNames[ms]);
+        // write list of supported modeswitches
+        for ms in (msAllPas2jsModeSwitches-AllLanguageModes) do
+          Log.LogPlain(SModeSwitchNames[ms]);
       end;
     'o':
       begin
@@ -3737,6 +3710,7 @@ begin
         Log.LogPlain('EnumNumbers');
         Log.LogPlain('RemoveNotUsedPrivates');
         Log.LogPlain('RemoveNotUsedDeclarations');
+        Log.LogPlain('ShortRefGlobals');
       end;
     't':
       // write list of supported targets
@@ -3762,6 +3736,40 @@ begin
     Log.LogPlain(InfoMsg);
 end;
 
+function TPas2jsCompiler.HandleOptionOptimization(C: Char; aValue: String): Boolean;
+Var
+  Enable: Boolean;
+begin
+  Result:=True;
+  case C of
+  '-': Options:=Options-coAllOptimizations+coO0;
+  '1': Options:=Options-coAllOptimizations+coO1;
+  '2': Options:=Options-coAllOptimizations+coO2;
+  'o':
+    begin
+    if aValue='' then
+      ParamFatal('missing -Oo option');
+    Enable:=true;
+    c:=aValue[length(aValue)];
+    if c in ['+','-'] then
+    begin
+      Enable:=c='+';
+      Delete(aValue,length(aValue),1);
+    end;
+    Case LowerCase(aValue) of
+     'enumnumbers': SetOption(coEnumValuesAsNumbers,Enable);
+     'removenotusedprivates': SetOption(coKeepNotUsedPrivates,not Enable);
+     'removenotuseddeclarations': SetOption(coKeepNotUsedDeclarationsWPO,not Enable);
+     'shortrefglobals': SetOption(coShortRefGlobals,not Enable);
+    else
+      Log.LogMsgIgnoreFilter(nUnknownOptimizationOption,[QuoteStr(aValue)]);
+    end;
+    end;
+  else
+    Result:=False;
+  end;
+end;
+
 procedure TPas2jsCompiler.ReadParam(Param: string; Quick, FromCmdLine: boolean);
 
   procedure UnknownParam;
@@ -4724,11 +4732,12 @@ begin
   w('  -O<x>  : Optimizations:');
   w('    -O-  : Disable optimizations');
   w('    -O1  : Level 1 optimizations (quick and debugger friendly)');
-  //w('    -O2  : Level 2 optimizations (Level 1 + not debugger friendly)');
+  w('    -O2  : Level 2 optimizations (Level 1 + not debugger friendly)');
   w('    -Oo<x>: Enable or disable optimization. The x is case insensitive:');
   w('      -OoEnumNumbers[-]: write enum value as number instead of name. Default in -O1.');
   w('      -OoRemoveNotUsedPrivates[-]: Default is enabled');
   w('      -OoRemoveNotUsedDeclarations[-]: Default enabled for programs with -Jc');
+  w('      -OoShortRefGlobals[-]: Insert JS local var for types and modules. Default enabled in -O2');
   w('  -P<x>  : Set target processor. Case insensitive:');
   w('    -Pecmascript5: default');
   w('    -Pecmascript6');
@@ -4955,6 +4964,7 @@ begin
   Log.LogPlain('Supported Optimizations:');
   Log.LogPlain('  EnumNumbers');
   Log.LogPlain('  RemoveNotUsedPrivates');
+  Log.LogPlain('  ShortRefGlobals');
   Log.LogLn;
   Log.LogPlain('Supported Whole Program Optimizations:');
   Log.LogPlain('  RemoveNotUsedDeclarations');

+ 1 - 1
packages/pastojs/src/pas2jsutils.pp

@@ -1,4 +1,4 @@
-unit pas2jsutils;
+unit Pas2JSUtils;
 {
     This file is part of the Free Component Library (FCL)
     Copyright (c) 2018  Mattias Gaertner  [email protected]

+ 68 - 68
packages/pastojs/tests/tcgenerics.pas

@@ -102,7 +102,7 @@ begin
   ConvertProgram;
   CheckSource('TestGen_RecordEmpty',
     LinesToStr([ // statements
-    'rtl.recNewT($mod, "TRecA$G1", function () {',
+    'rtl.recNewT(this, "TRecA$G1", function () {',
     '  this.$eq = function (b) {',
     '    return true;',
     '  };',
@@ -110,8 +110,8 @@ begin
     '    return this;',
     '  };',
     '});',
-    'this.a = $mod.TRecA$G1.$new();',
-    'this.b = $mod.TRecA$G1.$new();',
+    'this.a = this.TRecA$G1.$new();',
+    'this.b = this.TRecA$G1.$new();',
     '']),
     LinesToStr([ // $mod.$main
     'if ($mod.a.$eq($mod.b)) ;'
@@ -144,7 +144,7 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Record_ClassProc',
     LinesToStr([ // statements
-    'rtl.recNewT($mod, "TPoint$G1", function () {',
+    'rtl.recNewT(this, "TPoint$G1", function () {',
     '  this.x = 0;',
     '  this.$eq = function (b) {',
     '    return true;',
@@ -159,7 +159,7 @@ begin
     '    $mod.TPoint$G1.Fly();',
     '  };',
     '}, true);',
-    'this.p = $mod.TPoint$G1.$new();',
+    'this.p = this.TPoint$G1.$new();',
     '']),
     LinesToStr([ // $mod.$main
     '$mod.TPoint$G1.x = $mod.p.x + 10;',
@@ -187,7 +187,7 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Record_ClassVarRecord_Program',
     LinesToStr([ // statements
-    'rtl.recNewT($mod, "TBird", function () {',
+    'rtl.recNewT(this, "TBird", function () {',
     '  this.b = 0;',
     '  this.$eq = function (b) {',
     '    return this.b === b.b;',
@@ -197,7 +197,7 @@ begin
     '    return this;',
     '  };',
     '});',
-    'rtl.recNewT($mod, "TAnt$G1", function () {',
+    'rtl.recNewT(this, "TAnt$G1", function () {',
     '  this.x = $mod.TBird.$new();',
     '  this.$eq = function (b) {',
     '    return true;',
@@ -206,7 +206,7 @@ begin
     '    return this;',
     '  };',
     '}, true);',
-    'this.f = $mod.TAnt$G1.$new();',
+    'this.f = this.TAnt$G1.$new();',
     '']),
     LinesToStr([ // $mod.$main
     '$mod.f.x.b = $mod.f.x.b + 10;',
@@ -244,7 +244,7 @@ begin
     'rtl.module("UnitA", ["system"], function () {',
     '  var $mod = this;',
     '  var $impl = $mod.$impl;',
-    '  rtl.recNewT($mod, "TAnt$G1", function () {',
+    '  rtl.recNewT(this, "TAnt$G1", function () {',
     '    this.$initSpec = function () {',
     '      this.x = $impl.TBird.$new();',
     '      this.a = rtl.arraySetLength(null, $impl.TBird, 2);',
@@ -307,7 +307,7 @@ begin
   CheckSource('TestGen_Record_RTTI_UnitImpl',
     LinesToStr([ // statements
     'var $impl = $mod.$impl;',
-    'rtl.recNewT($mod, "TAnt$G1", function () {',
+    'rtl.recNewT(this, "TAnt$G1", function () {',
     '  var $r = $mod.$rtti.$Record("TAnt<Test1.TBird>", {});',
     '  this.$initSpec = function () {',
     '    this.x = $impl.TBird.$new();',
@@ -356,13 +356,13 @@ begin
   ConvertProgram;
   CheckSource('TestGen_ClassEmpty',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '});',
     'this.a = null;',
     'this.b = null;',
@@ -390,13 +390,13 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_EmptyMethod',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '  this.Fly = function (w) {',
     '    var Result = 0;',
     '    return Result;',
@@ -449,13 +449,13 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_TList',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TList$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TList$G1", this.TObject, function () {',
     '  this.$init = function () {',
     '    $mod.TObject.$init.call(this);',
     '    this.FItems = [];',
@@ -518,19 +518,19 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_TCustomList',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TCustomList$G2", $mod.TObject, function () {',
+    'rtl.createClass(this, "TCustomList$G2", this.TObject, function () {',
     '  this.PrepareAddingItem = function () {',
     '    var Result = 0;',
     '    return Result;',
     '  };',
     '});',
-    'rtl.createClass($mod, "TList$G1", $mod.TCustomList$G2, function () {',
+    'rtl.createClass(this, "TList$G1", this.TCustomList$G2, function () {',
     '  this.Add = function () {',
     '    var Result = 0;',
     '    Result = this.PrepareAddingItem();',
@@ -559,15 +559,15 @@ begin
   ConvertProgram;
   CheckSource('TestGen_ClassAncestor',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G2", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G2", this.TObject, function () {',
     '});',
-    'rtl.createClass($mod, "TEagle$G1", $mod.TBird$G2, function () {',
+    'rtl.createClass(this, "TEagle$G1", this.TBird$G2, function () {',
     '});',
     'this.a = null;',
     '']),
@@ -598,13 +598,13 @@ begin
   CheckSource('TestGen_Class_TypeInfo',
     LinesToStr([ // statements
     '$mod.$rtti.$Class("TBird<System.Word>");',
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '  this.$init = function () {',
     '    $mod.TObject.$init.call(this);',
     '    this.m = 0;',
@@ -643,7 +643,7 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_TypeOverload',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -674,13 +674,13 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_ClassProperty',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '  this.fSize = 0;',
     '});',
     '']),
@@ -724,13 +724,13 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_ClassProc',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TPoint$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TPoint$G1", this.TObject, function () {',
     '  this.x = 0;',
     '  this.Fly = function () {',
     '    $mod.TPoint$G1.x = $mod.TPoint$G1.x + 3;',
@@ -787,20 +787,20 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_ClassConstructor',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
     'this.count = 0;',
-    'rtl.createClass($mod, "TPoint$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TPoint$G1", this.TObject, function () {',
     '  this.x = 0;',
     '  this.Fly = function () {',
     '  };',
     '});',
     'this.r = null;',
-    'rtl.createClass($mod, "TPoint$G2", $mod.TObject, function () {',
+    'rtl.createClass(this, "TPoint$G2", this.TObject, function () {',
     '  this.x = 0;',
     '  this.Fly = function () {',
     '  };',
@@ -845,19 +845,19 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_TypeCastSpecializesWarn',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '  this.$init = function () {',
     '    $mod.TObject.$init.call(this);',
     '    this.F = 0;',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G2", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G2", this.TObject, function () {',
     '  this.$init = function () {',
     '    $mod.TObject.$init.call(this);',
     '    this.F = "";',
@@ -893,19 +893,19 @@ begin
   ConvertProgram;
   CheckSource('TestGen_Class_TypeCastSpecializesJSValueNoWarn',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '  this.$init = function () {',
     '    $mod.TObject.$init.call(this);',
     '    this.F = 0;',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G2", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G2", this.TObject, function () {',
     '  this.$init = function () {',
     '    $mod.TObject.$init.call(this);',
     '    this.F = undefined;',
@@ -1001,7 +1001,7 @@ begin
     LinesToStr([ // statements
     'rtl.module("UnitA", ["system"], function () {',
     '  var $mod = this;',
-    '  rtl.createClass($mod, "TBird$G1", pas.system.TObject, function () {',
+    '  rtl.createClass(this, "TBird$G1", pas.system.TObject, function () {',
     '    this.c = 13;',
     '    var c$1 = 14;',
     '    this.Create$1 = function (w) {',
@@ -1012,7 +1012,7 @@ begin
     '      return this;',
     '    };',
     '  });',
-    '  rtl.createClass($mod, "TBird$G2", pas.system.TObject, function () {',
+    '  rtl.createClass(this, "TBird$G2", pas.system.TObject, function () {',
     '    this.c = 13;',
     '    var c$1 = 14;',
     '    this.Create$1 = function (w) {',
@@ -1072,15 +1072,15 @@ begin
     LinesToStr([ // statements
     '$mod.$rtti.$Class("TAnt<System.Word>");',
     '$mod.$rtti.$Class("TFish<System.Word>");',
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TPersistent", $mod.TObject, function () {',
+    'rtl.createClass(this, "TPersistent", this.TObject, function () {',
     '});',
-    'rtl.createClass($mod, "TAnt$G2", $mod.TPersistent, function () {',
+    'rtl.createClass(this, "TAnt$G2", this.TPersistent, function () {',
     '  this.$init = function () {',
     '    $mod.TPersistent.$init.call(this);',
     '    this.f = null;',
@@ -1092,7 +1092,7 @@ begin
     '  var $r = this.$rtti;',
     '  $r.addField("f", $mod.$rtti["TFish<System.Word>"]);',
     '}, "TAnt<System.Word>");',
-    'rtl.createClass($mod, "TFish$G2", $mod.TPersistent, function () {',
+    'rtl.createClass(this, "TFish$G2", this.TPersistent, function () {',
     '  this.$init = function () {',
     '    $mod.TPersistent.$init.call(this);',
     '    this.a = null;',
@@ -1144,7 +1144,7 @@ begin
     'rtl.module("UnitA", ["system"], function () {',
     '  var $mod = this;',
     '  var $impl = $mod.$impl;',
-    '  rtl.createClass($mod, "TAnt$G1", pas.system.TObject, function () {',
+    '  rtl.createClass(this, "TAnt$G1", pas.system.TObject, function () {',
     '    this.$initSpec = function () {',
     '      this.x = $impl.TBird.$new();',
     '      this.a = rtl.arraySetLength(null, $impl.TBird, 2);',
@@ -1312,11 +1312,11 @@ begin
   ConvertProgram;
   CheckSource('TestGen_ExtClass_RTTI',
     LinesToStr([ // statements
-    '$mod.$rtti.$ExtClass("TGJSSET<System.JSValue>", {',
+    'this.$rtti.$ExtClass("TGJSSET<System.JSValue>", {',
     '  jsclass: "SET"',
     '});',
-    '$mod.$rtti.$RefToProcVar("TJSSetEventProc", {',
-    '  procsig: rtl.newTIProcSig([["value", rtl.jsvalue], ["key", rtl.nativeint], ["set_", $mod.$rtti["TGJSSET<System.JSValue>"]]])',
+    'this.$rtti.$RefToProcVar("TJSSetEventProc", {',
+    '  procsig: rtl.newTIProcSig([["value", rtl.jsvalue], ["key", rtl.nativeint], ["set_", this.$rtti["TGJSSET<System.JSValue>"]]])',
     '});',
     'this.p = null;',
     '']),
@@ -1358,7 +1358,7 @@ begin
     'rtl.module("UnitA", ["system"], function () {',
     '  var $mod = this;',
     '  var $impl = $mod.$impl;',
-    '  $mod.$rtti.$ExtClass("TAnt<UnitA.TBird>", {',
+    '  this.$rtti.$ExtClass("TAnt<UnitA.TBird>", {',
     '    jsclass: "SET"',
     '  });',
     '  $mod.$implcode = function () {',
@@ -1422,15 +1422,15 @@ begin
   ConvertProgram;
   CheckSource('TestGen_ClassInterface_Corba',
     LinesToStr([ // statements
-    'rtl.createInterface($mod, "IUnknown", "{00000000-0000-0000-C000-000000000046}", [], null);',
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createInterface(this, "IUnknown", "{00000000-0000-0000-C000-000000000046}", [], null);',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createInterface($mod, "IBird$G2", "{33AB51C6-6240-3BDF-B4B0-D48A593EAB0A}", ["GetSize", "SetSize", "DoIt"], $mod.IUnknown);',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createInterface(this, "IBird$G2", "{33AB51C6-6240-3BDF-B4B0-D48A593EAB0A}", ["GetSize", "SetSize", "DoIt"], this.IUnknown);',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '  rtl.addIntf(this, $mod.IBird$G2);',
     '});',
     'this.BirdIntf = null;',
@@ -1461,9 +1461,9 @@ begin
   ConvertProgram;
   CheckSource('TestGen_ClassInterface_InterfacedObject',
     LinesToStr([ // statements
-    'rtl.createInterface($mod, "IComparer$G2", "{505778ED-F783-4456-9691-32F419CC5E18}", ["Compare"], pas.system.IUnknown);',
+    'rtl.createInterface(this, "IComparer$G2", "{505778ED-F783-4456-9691-32F419CC5E18}", ["Compare"], pas.system.IUnknown);',
     'this.aComparer = null;',
-    'rtl.createClass($mod, "TComparer$G1", pas.system.TInterfacedObject, function () {',
+    'rtl.createClass(this, "TComparer$G1", pas.system.TInterfacedObject, function () {',
     '  this.Compare = function (Left, Right) {',
     '    var Result = 0;',
     '    return Result;',
@@ -1497,7 +1497,7 @@ begin
   ConvertProgram;
   CheckSource('TestGen_InlineSpec_Constructor',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -1506,7 +1506,7 @@ begin
     '    return this;',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '});',
     'this.b = null;',
     '']),
@@ -1546,13 +1546,13 @@ begin
     'rtl.module("UnitA", ["system"], function () {',
     '  var $mod = this;',
     '  var $impl = $mod.$impl;',
-    '  rtl.createClass($mod, "TBird$G1", pas.system.TObject, function () {',
+    '  rtl.createClass(this, "TBird$G1", pas.system.TObject, function () {',
     '    this.Fly = function () {',
     '      $impl.DoIt();',
     '    };',
     '  });',
     '  this.b = null;',
-    '  rtl.createClass($mod, "TBird$G2", pas.system.TObject, function () {',
+    '  rtl.createClass(this, "TBird$G2", pas.system.TObject, function () {',
     '    this.Fly = function () {',
     '      $impl.DoIt();',
     '    };',
@@ -1589,13 +1589,13 @@ begin
   ConvertProgram;
   CheckSource('TestGen_IntAssignTemplVar',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '  this.$init = function () {',
     '    $mod.TObject.$init.call(this);',
     '    this.m = 0;',
@@ -1636,14 +1636,14 @@ begin
   ConvertProgram;
   CheckSource('TestGen_TypeCastDotField',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
     '  };',
     '});',
     'this.o = null;',
-    'rtl.createClass($mod, "TBird$G1", $mod.TObject, function () {',
+    'rtl.createClass(this, "TBird$G1", this.TObject, function () {',
     '  this.$init = function () {',
     '    $mod.TObject.$init.call(this);',
     '    this.Field = 0;',
@@ -1682,7 +1682,7 @@ begin
   ConvertProgram;
   CheckSource('TestGen_HelperForArray',
     LinesToStr([ // statements
-    'rtl.createHelper($mod, "TWordArrHelper", null, function () {',
+    'rtl.createHelper(this, "TWordArrHelper", null, function () {',
     '  this.Fly = function (w) {',
     '  };',
     '});',
@@ -2013,7 +2013,7 @@ begin
   ConvertProgram;
   CheckSource('TestGenMethod_ObjFPC',
     LinesToStr([ // statements
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -2069,13 +2069,13 @@ begin
     'rtl.module("UnitA", ["system"], function () {',
     '  var $mod = this;',
     '  var $impl = $mod.$impl;',
-    '  $mod.$rtti.$DynArray("TDyn<UnitA.TBird>", {});',
+    '  this.$rtti.$DynArray("TDyn<UnitA.TBird>", {});',
     '  this.TStatic$G1$clone = function (a) {',
     '    var r = [];',
     '    for (var i = 0; i < 2; i++) r.push($impl.TBird.$clone(a[i]));',
     '    return r;',
     '  };',
-    '  $mod.$rtti.$StaticArray("TStatic<UnitA.TBird>", {',
+    '  this.$rtti.$StaticArray("TStatic<UnitA.TBird>", {',
     '    dims: [2]',
     '  });',
     '  $mod.$implcode = function () {',
@@ -2195,7 +2195,7 @@ begin
     'rtl.module("UnitA", ["system"], function () {',
     '  var $mod = this;',
     '  var $impl = $mod.$impl;',
-    '  $mod.$rtti.$ProcVar("TAnt<UnitA.TBird>", {',
+    '  this.$rtti.$ProcVar("TAnt<UnitA.TBird>", {',
     '    init: function () {',
     '      this.procsig = rtl.newTIProcSig([["a", $mod.$rtti["TBird"], 2]], $mod.$rtti["TBird"]);',
     '    }',

文件差異過大導致無法顯示
+ 125 - 124
packages/pastojs/tests/tcmodules.pas


+ 83 - 41
packages/pastojs/tests/tcoptimizations.pas

@@ -17,7 +17,7 @@
    ./testpas2js --suite=TTestOptimizations
    ./testpas2js --suite=TTestOptimizations.TestOmitLocalVar
 }
-unit tcoptimizations;
+unit TCOptimizations;
 
 {$mode objfpc}{$H+}
 
@@ -26,7 +26,7 @@ interface
 uses
   Classes, SysUtils, testregistry, fppas2js, pastree,
   PScanner, Pas2jsUseAnalyzer, PasResolver, PasResolveEval,
-  tcmodules;
+  TCModules;
 
 type
 
@@ -56,17 +56,10 @@ type
 
   TTestOptimizations = class(TCustomTestOptimizations)
   published
-    // unit optimization: jsaliasglobals
-    procedure TestOptAliasGlobals_Program;
-    procedure TestOptAliasGlobals_Unit_FromIntfImpl_ToIntfImpl;
-    // ToDo: external var, const, class
-    // ToDo: RTTI
-    // ToDo: typeinfo(var), typeinfo(type)
-    // ToDo: resourcestring
-    // ToDo: Global EnumType, EnumValue, EnumType.Value, unit.EnumType.Value
-    // ToDo: Nested EnumType: EnumValue, EnumType.Value, unit.aType.EnumType.Value, aType.EnumType.Value, Instance.EnumType.Value
-    // ToDo: Instance.RecordType, Instance.RecordType.ClassVar
-    // ToDo: ClassVarRecord
+    // unit optimization: jsshortrefglobals
+    procedure TestOptShortRefGlobals_Program;
+    procedure TestOptShortRefGlobals_Unit_FromIntfImpl_ToIntfImpl;
+    procedure TestOptShortRefGlobals_Property;
 
     // Whole Program Optimization
     procedure TestWPO_OmitLocalVar;
@@ -199,7 +192,7 @@ end;
 
 { TTestOptimizations }
 
-procedure TTestOptimizations.TestOptAliasGlobals_Program;
+procedure TTestOptimizations.TestOptShortRefGlobals_Program;
 begin
   AddModuleWithIntfImplSrc('UnitA.pas',
   LinesToStr([
@@ -224,7 +217,7 @@ begin
 
   StartProgram(true,[supTObject]);
   Add([
-  '{$optimization JSAliasGlobals}',
+  '{$optimization JSShortRefGlobals}',
   'uses unita;',
   'type',
   '  TEagle = class(TBird)',
@@ -249,12 +242,12 @@ begin
   '  c:=cRedBlue;',
   '']);
   ConvertProgram;
-  CheckSource('TestOptAliasGlobals_Program',
+  CheckSource('TestOptShortRefGlobals_Program',
     LinesToStr([
     'var $lm = pas.UnitA;',
     'var $lt = $lm.TBird;',
     'var $lt1 = $lm.TRec;',
-    'rtl.createClass($mod, "TEagle", $lt, function () {',
+    'rtl.createClass(this, "TEagle", $lt, function () {',
     '  this.Run = function (w) {',
     '    var Result = 0;',
     '    return Result;',
@@ -277,7 +270,7 @@ begin
     '']));
 end;
 
-procedure TTestOptimizations.TestOptAliasGlobals_Unit_FromIntfImpl_ToIntfImpl;
+procedure TTestOptimizations.TestOptShortRefGlobals_Unit_FromIntfImpl_ToIntfImpl;
 begin
   AddModuleWithIntfImplSrc('UnitA.pas',
   LinesToStr([
@@ -311,7 +304,7 @@ begin
     '']));
   StartUnit(true,[supTObject]);
   Add([
-  '{$optimization JSAliasGlobals}',
+  '{$optimization JSShortRefGlobals}',
   'interface',
   'uses unita;',
   'type',
@@ -354,7 +347,7 @@ begin
   '  RedAnt.Run;',
   '']);
   ConvertUnit;
-  CheckSource('TestOptAliasGlobals_Unit_FromIntfImpl_ToIntfImpl',
+  CheckSource('TestOptShortRefGlobals_Unit_FromIntfImpl_ToIntfImpl',
     LinesToStr([
     'var $impl = $mod.$impl;',
     'var $lm = pas.UnitA;',
@@ -363,7 +356,7 @@ begin
     'var $lt1 = null;',
     'var $lt2 = null;',
     'var $lt3 = null;',
-    'rtl.createClass($mod, "TEagle", $lt, function () {',
+    'rtl.createClass(this, "TEagle", $lt, function () {',
     '  this.Fly = function () {',
     '    $impl.TRedAnt.$create("Create");',
     '    $lt1.$create("Create");',
@@ -402,6 +395,55 @@ begin
     '']));
 end;
 
+procedure TTestOptimizations.TestOptShortRefGlobals_Property;
+begin
+  AddModuleWithIntfImplSrc('UnitA.pas',
+  LinesToStr([
+    'type',
+    '  TBird = class',
+    '    FWing: TObject;',
+    '    class var FLeg: TObject;',
+    '  public',
+    '    property Wing: TObject read FWing write FWing;',
+    '    class property Leg: TObject read FLeg write FLeg;',
+    '  end;',
+    '']),
+  LinesToStr([
+    '']));
+  StartUnit(true,[supTObject]);
+  Add([
+  '{$optimization JSShortRefGlobals}',
+  'interface',
+  'uses unita;',
+  'type',
+  '  TEagle = class(TBird)', // intf-JS to intf-uses
+  '    procedure Fly(o: TObject);',
+  '  end;',
+  'implementation',
+  'procedure TEagle.Fly(o: TObject);',
+  'begin',
+  '  Fly(Wing);',
+  '  Fly(Leg);',
+  'end;',
+  '']);
+  ConvertUnit;
+  CheckSource('TestOptShortRefGlobals_Property',
+    LinesToStr([
+    'var $lm = pas.UnitA;',
+    'var $lt = $lm.TBird;',
+    'rtl.createClass(this, "TEagle", $lt, function () {',
+    '  this.Fly = function (o) {',
+    '    this.Fly(this.FWing);',
+    '    this.Fly(this.FLeg);',
+    '  };',
+    '});',
+    '']),
+    LinesToStr([
+    '']),
+    LinesToStr([
+    '']));
+end;
+
 procedure TTestOptimizations.TestWPO_OmitLocalVar;
 begin
   StartProgram(false);
@@ -605,7 +647,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_OmitRecordMember',
     LinesToStr([
-    'rtl.recNewT($mod, "TRec", function () {',
+    'rtl.recNewT(this, "TRec", function () {',
     '  this.a = 0;',
     '  this.$eq = function (b) {',
     '    return this.a === b.a;',
@@ -615,7 +657,7 @@ begin
     '    return this;',
     '  };',
     '});',
-    'this.r = $mod.TRec.$new();',
+    'this.r = this.TRec.$new();',
     '']),
     LinesToStr([
     '$mod.r.a = 3;',
@@ -653,7 +695,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_TObject',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -693,7 +735,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_Class_TObject',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -725,7 +767,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_OmitClassField',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '    this.a = 0;',
     '  };',
@@ -754,7 +796,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_OmitClassMethod',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -784,7 +826,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_OmitClassMethod',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -820,7 +862,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_OmitClassPropertyGetter1',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '    this.FFoo = false;',
     '  };',
@@ -851,7 +893,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_OmitClassPropertyGetter2',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '    this.FFoo = false;',
     '  };',
@@ -892,7 +934,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_OmitClassPropertySetter1',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '    this.FFoo = false;',
     '  };',
@@ -923,7 +965,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_OmitClassPropertySetter2',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '    this.FFoo = false;',
     '  };',
@@ -970,7 +1012,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_Class_KeepNewInstance',
     LinesToStr([
-    'rtl.createClassExt($mod, "TBird", Object, "NewInstance", function () {',
+    'rtl.createClassExt(this, "TBird", Object, "NewInstance", function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -1019,7 +1061,7 @@ begin
   ConvertProgram;
   CheckSource('TestWPO_CallInherited',
     LinesToStr([
-    'rtl.createClass($mod, "TObject", null, function () {',
+    'rtl.createClass(this, "TObject", null, function () {',
     '  this.$init = function () {',
     '  };',
     '  this.$final = function () {',
@@ -1029,7 +1071,7 @@ begin
     '  this.DoB = function () {',
     '  };',
     '});',
-    ' rtl.createClass($mod, "TMobile", $mod.TObject, function () {',
+    ' rtl.createClass(this, "TMobile", this.TObject, function () {',
     '  this.DoA$1 = function () {',
     '    $mod.TObject.DoA.call(this);',
     '  };',
@@ -1096,7 +1138,7 @@ begin
   LinesToStr([
   'rtl.module("system", [], function () {',
   '  var $mod = this;',
-  '  rtl.recNewT($mod, "TVarRec", function () {',
+  '  rtl.recNewT(this, "TVarRec", function () {',
   '    this.VType = 0;',
   '    this.VJSValue = undefined;',
   '    this.$eq = function (b) {',
@@ -1175,7 +1217,7 @@ begin
   LinesToStr([
   'rtl.module("unit1", ["system"], function () {',
   '  var $mod = this;',
-  '  rtl.createClass($mod, "TObject", null, function () {',
+  '  rtl.createClass(this, "TObject", null, function () {',
   '    this.$init = function () {',
   '      this.FA = 0;',
   '    };',
@@ -1250,7 +1292,7 @@ begin
   'rtl.module("program",["system"],function () {',
   '  var $mod = this;',
   '  this.gcBlack = 0;',
-  '  rtl.createClass($mod,"TObject",null,function () {',
+  '  rtl.createClass(this,"TObject",null,function () {',
   '    this.$init = function () {',
   '      this.FColor = 0;',
   '    };',
@@ -1294,10 +1336,10 @@ begin
   ExpectedSrc:=LinesToStr([
     'rtl.module("program", ["system"], function () {',
     '  var $mod = this;',
-    '  $mod.$rtti.$DynArray("TArrB", {',
+    '  this.$rtti.$DynArray("TArrB", {',
     '    eltype: rtl.string',
     '  });',
-    '  rtl.createClass($mod, "TObject", null, function () {',
+    '  rtl.createClass(this, "TObject", null, function () {',
     '    this.$init = function () {',
     '      this.PublicA = [];',
     '      this.PublishedB = [];',
@@ -1339,7 +1381,7 @@ begin
   ExpectedSrc:=LinesToStr([
     'rtl.module("program", ["system"], function () {',
     '  var $mod = this;',
-    '  $mod.$rtti.$DynArray("TArrB", {',
+    '  this.$rtti.$DynArray("TArrB", {',
     '    eltype: rtl.string',
     '  });',
     '  this.A = [];',

+ 1 - 0
packages/pastojs/tests/testpas2js.lpi

@@ -59,6 +59,7 @@
       <Unit4>
         <Filename Value="tcoptimizations.pas"/>
         <IsPartOfProject Value="True"/>
+        <UnitName Value="TCOptimizations"/>
       </Unit4>
       <Unit5>
         <Filename Value="tcsrcmap.pas"/>

部分文件因文件數量過多而無法顯示