Bläddra i källkod

pastojs: remove empty $impl

git-svn-id: trunk@35736 -
Mattias Gaertner 8 år sedan
förälder
incheckning
4bce2e2b4d
2 ändrade filer med 59 tillägg och 38 borttagningar
  1. 45 17
      packages/pastojs/src/fppas2js.pp
  2. 14 21
      packages/pastojs/tests/tcmodules.pas

+ 45 - 17
packages/pastojs/src/fppas2js.pp

@@ -214,8 +214,6 @@ Works:
   - use 0o for octal literals
 
 ToDos:
-- codetools: external class not using TObject as ancestor
-- remove empty $impl
 - using external class must not mark the unit as used
 - compiler error code only when option -Jsomething given for fpc compatibility
 - -Jirtl.js-
@@ -907,6 +905,8 @@ type
     Function CreateTypeDecl(El: TPasType; AContext: TConvertContext): TJSElement;
     Function CreateVarDecl(El: TPasVariable; AContext: TConvertContext): TJSElement;
     Procedure AddToSourceElements(Src: TJSSourceElements; El: TJSElement);
+    procedure RemoveFromSourceElements(Src: TJSSourceElements;
+      El: TJSElement);
     function GetBuildInNames(bin: TPas2JSBuiltInName): string;
     procedure SetBuildInNames(bin: TPas2JSBuiltInName; const AValue: string);
     procedure SetPreservedWords(const AValue: TJSReservedWordList);
@@ -967,7 +967,7 @@ type
     Function CreateReferencePath(El: TPasElement; AContext : TConvertContext;
       Kind: TRefPathKind; Full: boolean = false; Ref: TResolvedReference = nil): string; virtual;
     Function CreateReferencePathExpr(El: TPasElement; AContext : TConvertContext; Full: boolean = false; Ref: TResolvedReference = nil): TJSPrimaryExpressionIdent; virtual;
-    Procedure CreateImplementationSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext);
+    Function CreateImplementationSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext): TJSElement;
     Procedure CreateInitSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext);
     Function CreateDotExpression(aParent: TPasElement; Left, Right: TJSElement): TJSElement; virtual;
     Function CreateReferencedSet(El: TPasElement; SetExpr: TJSElement): TJSElement; virtual;
@@ -2707,6 +2707,18 @@ begin
   end;
 end;
 
+procedure TPasToJSConverter.RemoveFromSourceElements(Src: TJSSourceElements;
+  El: TJSElement);
+var
+  Statements: TJSElementNodes;
+  i: Integer;
+begin
+  Statements:=Src.Statements;
+  for i:=Statements.Count-1 downto 0 do
+    if Statements[i].Node=El then
+      Statements.Delete(i);
+end;
+
 function TPasToJSConverter.GetBuildInNames(bin: TPas2JSBuiltInName): string;
 begin
   Result:=FBuiltInNames[bin];
@@ -2755,9 +2767,10 @@ Var
   UsesSection: TPasSection;
   ModuleName: String;
   IntfContext: TInterfaceContext;
-  VarSt: TJSVariableStatement;
+  ImplVarSt: TJSVariableStatement;
   VarDecl: TJSVarDeclaration;
-  AssignSt: TJSSimpleAssignStatement;
+  ImplAssignSt: TJSSimpleAssignStatement;
+  ImplDecl: TJSElement;
 begin
   Result:=Nil;
   OuterSrc:=TJSSourceElements(CreateElement(TJSSourceElements, El));
@@ -2815,25 +2828,38 @@ begin
       end
     else
       begin // unit
-      // add interface section
+      // add implementation object at top, so the interface elemwnts can add stuff
       if (FBuiltInNames[pbivnImplementation]<>'') and Assigned(El.ImplementationSection) then
         begin
         // add 'var $impl = {};'
-        VarSt:=TJSVariableStatement(CreateElement(TJSVariableStatement,El));
-        AddToSourceElements(Src,VarSt);
+        ImplVarSt:=TJSVariableStatement(CreateElement(TJSVariableStatement,El));
+        AddToSourceElements(Src,ImplVarSt);
         VarDecl:=TJSVarDeclaration(CreateElement(TJSVarDeclaration,El));
-        VarSt.A:=VarDecl;
+        ImplVarSt.A:=VarDecl;
         VarDecl.Name:=FBuiltInNames[pbivnImplementation];
         VarDecl.Init:=TJSEmptyBlockStatement(CreateElement(TJSEmptyBlockStatement,El.ImplementationSection));
         // add 'this.$impl = $impl;'
-        AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
-        AddToSourceElements(Src,AssignSt);
-        AssignSt.LHS:=CreateBuiltInIdentifierExpr('this.'+FBuiltInNames[pbivnImplementation]);
-        AssignSt.Expr:=CreateBuiltInIdentifierExpr(FBuiltInNames[pbivnImplementation]);
+        ImplAssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
+        AddToSourceElements(Src,ImplAssignSt);
+        ImplAssignSt.LHS:=CreateBuiltInIdentifierExpr('this.'+FBuiltInNames[pbivnImplementation]);
+        ImplAssignSt.Expr:=CreateBuiltInIdentifierExpr(FBuiltInNames[pbivnImplementation]);
+        end
+      else
+        begin
+        ImplVarSt:=nil;
+        ImplAssignSt:=nil;
         end;
       if Assigned(El.InterfaceSection) then
         AddToSourceElements(Src,ConvertDeclarations(El.InterfaceSection,IntfContext));
-      CreateImplementationSection(El,Src,IntfContext);
+      if ImplVarSt<>nil then
+        begin
+        ImplDecl:=CreateImplementationSection(El,Src,IntfContext);
+        if ImplDecl=nil then
+          begin
+          RemoveFromSourceElements(Src,ImplVarSt);
+          RemoveFromSourceElements(Src,ImplAssignSt);
+          end;
+        end;
       CreateInitSection(El,Src,IntfContext);
 
       // add optional implementation uses list: [<implementation uses1>,<uses2>, ...]
@@ -7170,17 +7196,19 @@ begin
   end;
 end;
 
-procedure TPasToJSConverter.CreateImplementationSection(El: TPasModule;
-  Src: TJSSourceElements; AContext: TConvertContext);
+function TPasToJSConverter.CreateImplementationSection(El: TPasModule;
+  Src: TJSSourceElements; AContext: TConvertContext): TJSElement;
 var
   Section: TImplementationSection;
 begin
+  Result:=nil;
   if not Assigned(El.ImplementationSection) then
     exit;
   Section:=El.ImplementationSection;
   // add implementation section
   // merge interface and implementation
-  AddToSourceElements(Src,ConvertDeclarations(Section,AContext));
+  Result:=ConvertDeclarations(Section,AContext);
+  AddToSourceElements(Src,Result);
 end;
 
 procedure TPasToJSConverter.CreateInitSection(El: TPasModule;

+ 14 - 21
packages/pastojs/tests/tcmodules.pas

@@ -766,6 +766,7 @@ var
   InitAssign: TJSSimpleAssignStatement;
   FunBody: TJSFunctionBody;
   InitName: String;
+  LastNode: TJSElement;
 begin
   if SkipTests then exit;
   try
@@ -840,14 +841,18 @@ begin
   FJSInitBody:=nil;
   if JSModuleSrc.Statements.Count>0 then
     begin
-    InitAssign:=JSModuleSrc.Statements.Nodes[JSModuleSrc.Statements.Count-1].Node as TJSSimpleAssignStatement;
-    if GetDottedIdentifier(InitAssign.LHS)='this.'+InitName then
+    LastNode:=JSModuleSrc.Statements.Nodes[JSModuleSrc.Statements.Count-1].Node;
+    if LastNode is TJSSimpleAssignStatement then
       begin
-      InitFunction:=InitAssign.Expr as TJSFunctionDeclarationStatement;
-      FJSInitBody:=InitFunction.AFunction.Body as TJSFunctionBody;
-      end
-    else if Module is TPasProgram then
-      CheckDottedIdentifier('init function',InitAssign.LHS,'this.'+InitName);
+      InitAssign:=LastNode as TJSSimpleAssignStatement;
+      if GetDottedIdentifier(InitAssign.LHS)='this.'+InitName then
+        begin
+        InitFunction:=InitAssign.Expr as TJSFunctionDeclarationStatement;
+        FJSInitBody:=InitFunction.AFunction.Body as TJSFunctionBody;
+        end
+      else if Module is TPasProgram then
+        CheckDottedIdentifier('init function',InitAssign.LHS,'this.'+InitName);
+      end;
     end;
 end;
 
@@ -1183,9 +1188,6 @@ begin
   ConvertUnit;
   CheckSource('TestEmptyUnit',
     LinesToStr([
-    'var $impl = {',
-    '};',
-    'this.$impl = $impl;'
     ]),
     '');
 end;
@@ -1199,10 +1201,7 @@ begin
   ConvertUnit;
   CheckSource('TestEmptyUnitUseStrict',
     LinesToStr([
-    '"use strict";',
-    'var $impl = {',
-    '};',
-    'this.$impl = $impl;'
+    '"use strict";'
     ]),
     '');
 end;
@@ -2051,10 +2050,7 @@ begin
   ConvertUnit;
   CheckSource('TestProcedureExternalOtherUnit',
     LinesToStr([
-    'var $impl = {',
-    '};',
-    'this.$impl = $impl;'
-    ]),
+    '']),
     LinesToStr([
     'Date.now();',
     'Date.now();',
@@ -8066,9 +8062,6 @@ begin
   ConvertUnit;
   CheckSource('TestExternalClass_ClassOtherUnit',
     LinesToStr([
-    'var $impl = {',
-    '};',
-    'this.$impl = $impl;',
     '']),
     LinesToStr([
     'ExtA.Id = ExtA.Id + 1;',