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

php: ability to declare extern methods in root namespace #4876

Closed
yar3333 opened this issue Feb 25, 2016 · 10 comments
Closed

php: ability to declare extern methods in root namespace #4876

yar3333 opened this issue Feb 25, 2016 · 10 comments
Milestone

Comments

@yar3333
Copy link
Contributor

yar3333 commented Feb 25, 2016

I try to create externs for standard functions:

@:native("")
extern class Native {
    static function echo(s:String) : Void;
}

class Test {
    static function main() {
        Native.echo("abc");
    }
}

Result php code:

<?php

class Test {
    public function __construct(){}
    static function main() {
        ::hecho("abc");   // MUST BE echo("abc")
    }
    function __toString() { return 'Test'; }
}

If this is not too complex, I ask to support @:native("") on php target.

@musou1500
Copy link

I don't know that Haxe has a plan to support @:native("").
But you can use __php__ or __call__

The Haxe Magic - Php Magic
Sorry If you already knew that.

@back2dos
Copy link
Member

back2dos commented Mar 3, 2016

So long as performance doesn't become an issue, you @:native the class to
one that implements __callStatic by using call_user_func_array to invoke
the global function (note though, that echo is technically not a function).

Otherwise I suggest writing a macro.

On Thu, Mar 3, 2016 at 5:36 AM, musou1500 notifications@github.com wrote:

I don't know that Haxe has a plan to support @:native("").
But you can use php or call

(The Haxe Magic - Php Magic)[
http://old.haxe.org/doc/advanced/magic#php-magic]
Sorry If you already knew that.


Reply to this email directly or view it on GitHub
#4876 (comment)
.

@yar3333
Copy link
Contributor Author

yar3333 commented Mar 3, 2016

Now I use __call__, but in PHP calling a function with null argument and without argument is a different thing (many functions have none-simple default values, some functions MUST BE called without some arguments - so, writing extern is difficult). Also, some functions support overloading.

I trying wrote a macro. The first problem - if macro function in class inside php package then compiler say me "you must not use php in macro". Second problem: compiler don't check types of macro function arguments, so I need to do that manually and macro functions became very complex.

So, only a really good way - support real externals for root functions. With working @:overload.

@yar3333
Copy link
Contributor Author

yar3333 commented Mar 3, 2016

For example, now extern for get_html_translation_table:

public static function get_html_translation_table(?table:Int, ?flags:Int, encoding="UTF-8") : NativeArray
    {
        if (untyped __physeq__(flags, null))
        {
            if (untyped __physeq__(table, null))
            {
                return untyped __call__('get_html_translation_table');
            }
            else
            {
                return untyped __call__('get_html_translation_table', table);
            }
        }
        else
        {
            return untyped __call__('get_html_translation_table', table, flags, encoding);
        }
    }

@mockey
Copy link
Contributor

mockey commented Mar 5, 2016

in PHP calling a function with null argument and without argument is a different thing

I wrote a couple of PHP externs recently and I agree that this is problem. A missing argument is always passed as null from Haxe. This even leads to runtime errors when the argument needs to be passed by reference. I tried to handle this with a macro but that didn't work. I don't remember the details, though.

But the function above is a bad example, because all its arguments have default values actually. I would write an extern for it like this:

public static inline function getHtmlTranslationTable(table:Int=0, flags:Int=2, encoding:String="UTF-8"):php.NativeArray
  return (untyped __call__)("get_html_translation_table", table, flags, encoding);

Inlining this helps a lot and generates relatively concise PHP code. It also has the nice effect, that you can pass null to get the default value (something you can't do in native PHP :-), e.g. getHtmlTranslationTable(null, null, "ISO-8859-1")will generate:get_html_translation_table(0, 2, "ISO-8859-1")`.

Also using __physeq__ is unnecessary, I think. All the == are translated to === already in current Haxe AFAIK.

@yar3333
Copy link
Contributor Author

yar3333 commented Mar 7, 2016

Thank you, @mockey, you right: haxe's == translated into php's ===, so __physeq__ may be simplified.
Also, you right - in most cases we can use numbers, but using number as default value instead readable constant is not good practice, as for me.

@mockey
Copy link
Contributor

mockey commented Mar 7, 2016

@yar3333: Yeah right, looking up constant values is not so nice. You can define an @:enum abstract, if you want to have constant names. But you'd have to define it with numbers as well unfortunately, see: #4770. This whole untyped __php__ magic is rather limited.
The code above is just an example what is currently possible, but it's an awful work with a lot of workarounds to do externs like this. Handling of global functions, handling of constants, handling of native arrays, correctly dealing with optional arguments, all this should be much easier. I think we really need a new php target...

@Simn
Copy link
Member

Simn commented Apr 2, 2016

I'm not sure if this was closed by the linked PR or not...

@mockey
Copy link
Contributor

mockey commented Apr 2, 2016

Generally it should be closed by the PR, not sure if @yar3333 has tried it or if he wanted something else....

But as I wrote here: #5006
there is this problem that the compilation server errors, when you have several externs using @:native("")(which you*d naturally have). I added a hack to typeload.ml that simply excludes the global paths from the check_module_types error here:
https://github.com/HaxeFoundation/haxe/blob/development/src/typing/typeload.ml#L2838
That makes the error go away. but I'm not sure if that's a good idea...

@Simn
Copy link
Member

Simn commented Apr 2, 2016

I'll consider it close then, the @:native issue is not strictly related.

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

No branches or pull requests

5 participants