thanhhovn / sharpkit

Automatically exported from code.google.com/p/sharpkit
0 stars 0 forks source link

Support multiple constructors in prototype mode #193

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
source:
    [JsType(JsMode.Prototype, NativeOverloads = false)]
    public class Foo
    {
        public Foo(int a) {}
        public Foo(int a, int b) {}
     }

output: 
shetab.Foo = function(a) {};
shetab.Foo = function(a,b) { }; //!!! clear old constrcutor!

Expected:
raise unsupported warning or support multiple constructors as follow:
shetab.Foo = function($$constructorVersion)
{
    var args = Array.prototype.slice.call(arguments, 1); //rested args
   if ( $$constructorVersion==1){ $$constructor1.call( args ); }
   if ( $$constructorVersion==2){ $$constructor2.call( args ); }
};

shetab._$$constructor1 = function(a){}
shetab._$$constructor2 = functions(a, b) {}

Original issue reported on code.google.com by Madnik7@gmail.com on 12 Aug 2012 at 5:58

GoogleCodeExporter commented 8 years ago

Original comment by DanelK...@gmail.com on 12 Aug 2012 at 7:23

GoogleCodeExporter commented 8 years ago
Prototype mode supports only one constructor, a compiler error should be thrown

Original comment by DanelK...@gmail.com on 19 Aug 2012 at 8:37

GoogleCodeExporter commented 8 years ago
It is so good to throw compiled error when NativeOverloads=true, but multiple 
constructors also can also be support in prototype mode when 
NativeOverloads=false. such as

[NativeOverloads=false]
foo = function(constructorVersion, arg1, arg2, ...)
{
    if (constructorVersion==1) $$constrcutor1(...)
   else if (constructorVersion==1) $$constrcutor2(...)
   .
   .
   .
}

Original comment by Madnik7@gmail.com on 19 Aug 2012 at 8:46

GoogleCodeExporter commented 8 years ago
I find NativeConstructors = false, but it seem it does not work in Prototype 
mode :(

Original comment by Madnik7@gmail.com on 19 Aug 2012 at 10:15

GoogleCodeExporter commented 8 years ago
There is no sufficient data to perform automatic overload resolution in 
runtime, there might be other options to solve this, but currently, you can 
implement multiple constructors using a single ctor, and set Export=false on 
the other ones.
There is excellent support for multiple ctors in clr mode, you might benefit in 
using it instead.

Original comment by DanelK...@gmail.com on 19 Aug 2012 at 1:31

GoogleCodeExporter commented 8 years ago
I currently use Export=false but I just like to make SharpKit better specially 
in Prototype mode

>>There is no sufficient data to perform automatic overload resolution in 
runtime

I think there is enough data when [NativeConstructors = false]

let show you example, I test it and it work fine.

    [JsType(JsMode.Prototype, NativeConstructors = false)]
    public class Foo
    {
        public Foo(JsString arg1)   { /*ctor1 body*/  }
        public Foo(JsString arg1, JsString arg2)  { /*ctor2 body*/  }
    }

    var f = new Foo("arg1", "arg2"); //I call costructor 2

can be generate like this:
                Foo = function (ctor) {
                        // default initialization such as member list here

                        //call user constructor
            ctor.apply(this, Array.prototype.slice.call(arguments, 1));
        };

        Foo.prototype.$$ctor1 = function (arg1) {
            //ctor1 body
            console.log(arg1);
        };

        Foo.prototype.$$ctor2 = function (arg1, arg2) {
            //ctor2 body
            console.log(arg1, arg2);
        };

        var s = new Foo(Foo.prototype.$$ctor2, "arg1", "arg2"); //compiler have enough data to generate Foo.prototype.$$ctor2 at compile time

--------------
Notes: 
1) Implementer set NativeConstructors = false so it will not create Foo object 
directly in JS codes without care.
2) Compiler have enough data to generate it Foo.prototype.$$ctor2

Please let me know If you like to I continue in this subject.
Regards

Original comment by Madnik7@gmail.com on 19 Aug 2012 at 2:19

GoogleCodeExporter commented 8 years ago
It's a nice idea, but this implementation will be limited to the number of 
arguments passed to a constructor - this means that multiple constructors with 
same number of arguments but of different types will not be supported. Also, 
optional parameters might cause wrong resolving of the ctors. It's an 
interesting idea nevertheless, kind of a manual override resolution in runtime, 
only problem is that it will be pretty limited.

Original comment by DanelK...@gmail.com on 20 Aug 2012 at 6:51

GoogleCodeExporter commented 8 years ago
Hi Danel

>> this means that multiple constructors with same number of arguments but of 
different types will not be supported. Also, optional parameters might cause 
wrong resolving of the ctors

I wonder why you say this?!
It is not kind of a manual override resolution in run-time!, it is override 
solution at compile time same as .NET compiler do for MSIL.
Their both supported with same way, because calling constructor generating at 
compile time and it does not sensitive to optional parameters and arguments 
type at runtime. Following example shows multiple constructor with same 
argument but different types.

[JsType(JsMode.Prototype, NativeConstructors = false)]
    public class Foo
    {
        public Foo(JsString arg1)   { /*ctor1 body*/  }
        public Foo(JsObject arg1)  { /*ctor2 body*/ }
    }

        var obj = new JsObject();
    var f = new Foo(obj); //I call costructor 2   /**** Of-course compiler knows I using ctor2 at compile time ****/

can be generate like this:
                Foo = function (ctor) {
                        // default initialization such as member list here

                        //call user constructor
            ctor.apply(this, Array.prototype.slice.call(arguments, 1));
        };

        Foo.prototype.$$ctor1 = function (arg1) {
            //ctor1 body
            console.log(arg1);
        };

        Foo.prototype.$$ctor2 = function (arg1) {
            //ctor2 body
            console.log(arg1);
        };

        var s = new Foo(Foo.prototype.$$ctor2, "arg1"); //compiler have enough data to generate Foo.prototype.$$ctor2 at compile time, EVEN with different time because it generate at compile time.

Its is same for optional parameter, I think it is total solution and not 
limited. let me know your idea.
Regards

Original comment by Madnik7@gmail.com on 20 Aug 2012 at 7:39

GoogleCodeExporter commented 8 years ago
I see, I didn't see this example before, you're the second person to offer this 
feature, so I think it should be implemented. What about this kind of 
implementation instead? (it might be simpler:)

Contact = function()
{
}
Contact.ctor1 = function(arg1)
{
   var $this = new Contact();
   //use '$this' instead of 'this'
   return $this;
}

Contact.ctor2 = function(arg1)
{
   var $this = new Contact();
   //use '$this' instead of 'this'
   return $this;
}

Now, SharpKit can directly call 'new Contact.ctor1()' without passing a 
reference to another constructor.

What do you think?

Original comment by DanelK...@gmail.com on 20 Aug 2012 at 8:19

GoogleCodeExporter commented 8 years ago
I feel so silly, your solution is much much better.
Regards

Original comment by Madnik7@gmail.com on 20 Aug 2012 at 8:28

GoogleCodeExporter commented 8 years ago
Heehee, thanks :-), I wouldn't have reached this solution if it wasn't for your 
suggestion. And it uses a bit of a JavaScript 'hack' when I return a new object 
from a constructor. But overall I think it's a cleaner and more native solution 
to this issue.

Thanks for great and productive discussion. You're very patient!

Original comment by DanelK...@gmail.com on 20 Aug 2012 at 8:31

GoogleCodeExporter commented 8 years ago

Original comment by yvan.rod...@gmail.com on 5 Dec 2012 at 5:13