nikic / scalar_objects

Extension that adds support for method calls on primitive types in PHP
MIT License
1.13k stars 44 forks source link

PHP-Parser and Scalar Objects? #30

Open HallofFamer opened 8 years ago

HallofFamer commented 8 years ago

Hi Nikic, I was wondering if its possible to write an extension for your PHP-Parser library that supports Scalar Objects syntax. It will be able to parse syntax from scalar objects, and it will also be able to transpile between code written with Scalar Objects with code written without Scalar Objects. Anyway here is a simple illustration.

Code with Scalar Objects: $capLetters = "this is a string"->toUpperCase();

Code without Scalar Objects: $capLetters = StringObject::toUpperCase("this is a string");

So as you see, the difference is simple that scalar objects extension converts a static call ScalarObject::method($scalar) to $scalar->method(). I think it shouldnt be very difficult, what do you think? Are you interested in making one? Or if possible I can give a try sometime in future when I have more time myself.

nikic commented 8 years ago

Converting "string"->method() into StringObject::method("string") is easy. The problem is that generally you will not be working on literals, but on variables. If you have $string->method(), you do not actually know that $string is a string (in the general case). As such, you'd have to transform it into something like

$string->method($args)
// to
(\is_object($string) ? $string->method() : call_primitive_method($string, 'method', $args))

This would have to be done with every single method call (unless you happen to have more specific type information). This would be fairly expensive (though I don't know how expensive exactly).

HallofFamer commented 8 years ago

I see. But I thought the point of a static analysis tool is that, well, it can infer the type of the variable, cant it? In my IDE it can tell the type of a variable all the time, although I am not sure if the PHP Parser can infer types from function/method call right now. If it cannot, then yes it will be necessary to transform some methods by the above code as you suggest.

Anyway I dont think its necessary that complex and expensive, since there will only be a few dozens of methods(ie. string::capitalize(), array::sort()) for primitives. Some of these method names are even duplicate(ie. string and array both have length() and replace() methods), so there will only be a small number of methods that will need to be taken care of.