View Issue Details

IDProjectCategoryView StatusLast Update
0038858pas2jstranspilerpublic2021-05-13 08:03
Reporterhenrique Assigned ToMattias Gaertner  
PrioritynormalSeverityminorReproducibilityalways
Status assignedResolutionopen 
PlatformPas2JsOSWindows 
Summary0038858: Subclass construction
DescriptionI'm creating a library for maps, and I had a problem with naming of the constructor in the generated JS.

I attach the project to the problems, where I declared one class inside the other.

In the generated JS, it declares the constructor line with only the external name of the innermost class, it ignores the class chain before that.
TagsNo tags attached.
Fixed in Revision
Attached Files

Relationships

related to 0038875 assignedMichael Van Canneyt Maps implementation 

Activities

henrique

2021-05-05 12:52

reporter  

Error.zip (575 bytes)

henrique

2021-05-05 14:46

reporter   ~0130765

I've attach the change I've made to work here.
0001-Nome-com-caminho-completo.patch (1,307 bytes)   
From 8333dce45f7ed16193e883b06f3212d81edd1a13 Mon Sep 17 00:00:00 2001
From: Henrique Gottardi Werlang <henriquewerlang@hotmail.com>
Date: Wed, 5 May 2021 11:42:32 -0300
Subject: [PATCH] Nome com caminho completo.

---
 packages/pastojs/src/fppas2js.pp | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/packages/pastojs/src/fppas2js.pp b/packages/pastojs/src/fppas2js.pp
index c46e74963f..d0c093d2ce 100644
--- a/packages/pastojs/src/fppas2js.pp
+++ b/packages/pastojs/src/fppas2js.pp
@@ -24804,6 +24804,19 @@ var
       Prepend(Path,CreateGlobalTypePath(ClassOrRec,AContext));
   end;
 
+  procedure PrependClassOrRecNameFullPath(var Path: string; ClassOrRec: TPasMembersType);
+  begin
+    while True do
+    begin
+      PrependClassOrRecName(Path, ClassOrRec);
+
+      if ClassOrRec.Parent.ClassType=TPasClassType then
+        ClassOrRec := ClassOrRec.Parent as TPasClassType
+      else
+        Break;
+    end;
+  end;
+
   function NeedsWithExpr: boolean;
   var
     Parent: TPasElement;
@@ -25090,7 +25103,7 @@ begin
 
         if Full then
           begin
-          PrependClassOrRecName(Result,TPasMembersType(ParentEl));
+          PrependClassOrRecNameFullPath(Result,TPasMembersType(ParentEl));
           break;
           end;
 
-- 
2.31.1.windows.1

henrique

2021-05-11 10:26

reporter   ~0130822

?

Michael Van Canneyt

2021-05-12 07:01

administrator   ~0130825

The constructor name for external classes must be "new".

{$mode objfpc}
{$modeswitch externalclass}
uses js;

Type

  TA = Class external name 'A' (TJSObject)
    Type
    TB = Class external name 'B' (TJSObject)
      constructor new;
      procedure doit;
    end;
   end;
   

var
  B : TA.TB;
  
begin
  B:=TA.TB.New;
  B.Doit;
end.

Will generate the following Javascript:

rtl.module("program",["System","JS"],function () {
  "use strict";
  var $mod = this;
  this.B = null;
  $mod.$main = function () {
    $mod.B = new A.B();
    $mod.B.doit();
  };
});

As you can see, it correctly uses A.B

henrique

2021-05-12 17:39

reporter   ~0130834

Does not work if you place more than two class levels, like this:


interface

{$modeswitch externalclass}

type
  TMyClass1 = class external name 'myclass1'
  public type
    TMyclass2 = class external name 'myclass2'
    public type
      TMyClass3 = class external name 'myclass3'
      public
        constructor MyConstructor;
      end;
    end;
  end;

procedure MakeError;

implementation

procedure MakeError;
var
  MyClass: TMyClass1.TMyClass2.TMyClass3;

begin
  MyClass := TMyClass1.TMyClass2.TMyClass3.MyConstructor;
end;

end.

Thre result JS is:

rtl.module("UnitError",["System"],function () {
  "use strict";
  var $mod = this;
  this.MakeError = function () {
    var MyClass = null;
    MyClass = new myclass3.MyConstructor();
  };
});

And should be like this:

rtl.module("UnitError",["System"],function () {
  "use strict";
  var $mod = this;
  this.MakeError = function () {
    var MyClass = null;
    MyClass = new myclass1.myclass2.myclass3.MyConstructor();
  };
});

Michael Van Canneyt

2021-05-12 17:58

administrator   ~0130836


Yes it does. But you MUST name your constructor "new".

unit taa;


interface

{$modeswitch externalclass}

type
  TMyClass1 = class external name 'myclass1'
  public type
    TMyclass2 = class external name 'myclass2'
    public type
      TMyClass3 = class external name 'myclass3'
      public
        constructor new;
      end;
    end;
  end;

procedure MakeError;

implementation

procedure MakeError;
var
  MyClass: TMyClass1.TMyClass2.TMyClass3;

begin
  MyClass := TMyClass1.TMyClass2.TMyClass3.New;
end;

end.

results in:
rtl.module("taa",["System"],function () {
  "use strict";
  var $mod = this;
  this.$rtti.$ExtClass("TMyClass1",{jsclass: "myclass1"});
  this.MakeError = function () {
    var MyClass = null;
    MyClass = new myclass1.myclass2.myclass3();
  };
});

Michael Van Canneyt

2021-05-13 05:18

administrator   ~0130843

I talked to Mattias, looks like there is a bug after all.

Issue History

Date Modified Username Field Change
2021-05-05 12:52 henrique New Issue
2021-05-05 12:52 henrique File Added: Error.zip
2021-05-05 14:46 henrique Note Added: 0130765
2021-05-05 14:46 henrique File Added: 0001-Nome-com-caminho-completo.patch
2021-05-11 10:26 henrique Note Added: 0130822
2021-05-12 07:01 Michael Van Canneyt Assigned To => Michael Van Canneyt
2021-05-12 07:01 Michael Van Canneyt Status new => resolved
2021-05-12 07:01 Michael Van Canneyt Resolution open => no change required
2021-05-12 07:01 Michael Van Canneyt Note Added: 0130825
2021-05-12 07:02 Michael Van Canneyt Relationship added related to 0038875
2021-05-12 17:39 henrique Status resolved => feedback
2021-05-12 17:39 henrique Resolution no change required => open
2021-05-12 17:39 henrique Note Added: 0130834
2021-05-12 17:58 Michael Van Canneyt Status feedback => resolved
2021-05-12 17:58 Michael Van Canneyt Resolution open => no change required
2021-05-12 17:58 Michael Van Canneyt Note Added: 0130836
2021-05-13 05:18 Michael Van Canneyt Status resolved => new
2021-05-13 05:18 Michael Van Canneyt Resolution no change required => open
2021-05-13 05:18 Michael Van Canneyt Note Added: 0130843
2021-05-13 05:18 Michael Van Canneyt Assigned To Michael Van Canneyt => Mattias Gaertner
2021-05-13 08:03 Mattias Gaertner Assigned To Mattias Gaertner =>
2021-05-13 08:03 Mattias Gaertner Assigned To => Mattias Gaertner
2021-05-13 08:03 Mattias Gaertner Status new => assigned