Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Static binding generator specification. #363

Closed
3 of 5 tasks
Plamen5kov opened this issue Feb 23, 2016 · 1 comment
Closed
3 of 5 tasks

[Proposal] Static binding generator specification. #363

Plamen5kov opened this issue Feb 23, 2016 · 1 comment

Comments

@Plamen5kov
Copy link
Contributor

What we want to do:

To comlete proposal implementation:

  • Rewrite javascript AST parser to support old functionality.
  • AST parser support for custom extend functionality (JavaProxy("com.my.ClassName") decorator)
  • Rewrite binding generator to use bcel library when creating custom/common java proxies.
  • Test generated java common extended proxies
  • Test generated java custom extended proxies

Analyze ES5

Analyze ES5 and extract all information concerning NativeScript. The information we need from the static analysis is:

  • For classes:
    • extend class name: android.widget.Button.extend(...)
    • overridden methods: ...({ method1=func(){}, method2=func(){}})
    • (optional) java proxy name: JavaProxy("com.example.MyActivity")
  • For interfaces
    • interface extend name: new android.app.Application.ActivityLifecycleCallbacks(...)
    • overridden methods: ...({ method1=func(){}, method2=func(){}})

What syntax should we support?

What syntax we shouldn't support?

IMPORTANT: it's not a good idea to support this scenario, because if a JavaProxy() is provided but no extend, the java.lang.Object class will be inherited implicitly.

Why analyze ES5?

  • Faster loading time.
  • To generate java proxies, which can't be created at runtime, because it's too late. An example would be a class that implements Android Application or Android Activity

Why generate java proxies at build-time?

What are java proxies? Android classes specialized to serve NativeScript.

Why do we need them? To have a way to "callback" Javascript and handle native events from Android among other things.

Two types of java proxies:

  • Common - General purpose java proxy. It can be created either at build-time or run-time.
  • Custom - Used to create custom class extends. These proxies can be generated only at build time and can be declared in the AndroidManifest.xml.

As you can see the two kinds of proxies are more or less the same for the exception of the decorator: @com.tns.JavaScriptImplementation(javaScriptFile = "app/myactivity.js") which is only necessary for the custom java proxy.

IMPORTANT: JavaProxy() decorator on the Javascript side and @com.tns.JavaScriptImplementation() anotaion on the Java side are necessary when dealing with custom proxies because otherwise the runtime won't be able to link the instances correctly.

Extend name specification

  • Common proxy

    Typescript

    class MyClass extends android.widget.Button {
    ...
    }

    ES5

    var MyClass = android.widget.Button.extend("ClassName", {...});

    Generates a java proxy named ClasName.java in com.tns.gen.android.widget namespace.

  • Custom proxy

    Typescript

    JavaProxy("com.my.ClassName")
    class MyClass extends android.widget.Button {
    ...
    }

    ES5

    var MyClass = android.widget.Button.extend("com.my.ClassName", {...});

    Generates a java proxy named ClasName.java in com.my namespace.

IMPORTANT: Extend naming is important, because it dictates where the class will be created and therefore how will it be accessed through Javascript.

Common extended classes

Common extend classes with pure ES5

var MyButton = android.widget.Button.extend("TestClass", {
    onClick1: function () {
    },
    onClick2: function () {
    }
})

Common extend classes ES5 parsed from Typescript

var TestClass = (function (_super) {
    __extends(ZZZZZ, _super);
    function TestClass() {
        _super.apply(this, arguments);
    }
    TestClass.prototype.TestClassMethod1 = function () {
    };
    TestClass.prototype.TestClassMethod2 = function () {
    };
    return TestClass;
})(passed.extend.Present);

Custom extend classes

Custom extend classes with pure ES5

var MyButton = android.widget.Button.extend("my.custom.TestClass", {
    onClick1: function () {
    },
    onClick2: function () {
    }
});

Custom extend classes with ES5 parsed from Typescript

var TestClass = (function (_super) {
    __extends(TestClass, _super);
    function TestClass() {
        _super.apply(this, arguments);
    }
    TestClass.prototype.TestClassMethod1 = function () {
    };
    TestClass.prototype.TestClassMethod2 = function () {
    };
    TestClass = __decorate([
        JavaProxy("javaProxy.path.Present")
    ], TestClass);
    return TestClass;
})(passed.extend.Present);

Interfaces

 var lifecycleCallbacks = new android.app.Application.ActivityLifecycleCallbacks({
     onActivityCreated: function (activity, bundle) {},
     onActivityDestroyed: function (activity) {},
     onActivityPaused: function (activity) {},
     onActivityResumed: function (activity) {},
     onActivitySaveInstanceState: function (activity, bundle) {},
     onActivityStarted: function (activity) {},
     onActivityStopped: function (activity) {}
 });

Not a good idea to support:

No extend with custom java proxy:

var TestClass = (function () {
    function TestClass() {
    }
    TestClass.prototype.TestClassMethod1 = function () {
    };
    TestClass.prototype.TestClassMethod2 = function () {
    };
    TestClass = __decorate([
        JavaProxy("javaProxy.path.Present")
    ], TestClass);
    return TestClass;
})();

Java proxy examples

Common proxy example

package com.tns.gen.android.view;

public class ViewGroup extends android.view.ViewGroup {
    private boolean __initialized;
    protected void onLayout(boolean param_0, int param_1) {
        if (!__initialized) {
            __initialized = true;
            com.tns.Platform.initInstance(this);
        }
            java.lang.Object[] params = new Object[2];
            params[0] = param_0;
            params[1] = param_1;
            com.tns.Platform.callJSMethod(this, "onLayout", void.class, params);
    }
}

Custom proxy example

// com/example/MyActivity.java
package com.example;

@com.tns.JavaScriptImplementation(javaScriptFile = "app/myactivity.js")
public class MyActivity extends android.app.Activity {
   public MyActivity() {
      com.tns.Platform.initInstance(this);
   }
   public void onCreate(android.os.Bundle param_0) {
      Object[] args = new Object[1];
      args[0] = param_0;
      com.tns.Platform.callJSMethod(this, "onCreate", void.class, args);
   }
}
@Plamen5kov
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants