bmewburn / vscode-intelephense

PHP intellisense for Visual Studio Code
https://intelephense.com
Other
1.63k stars 94 forks source link

Add support class_alias function #600

Open Sumanai opened 5 years ago

Sumanai commented 5 years ago

PHP has support for creating aliases for classes, but apparently, such classes are not recognized by the current version of Intelephense, there are no IDE hints. Documentation: https://www.php.net/manual/en/function.class-alias.php

KapitanOczywisty commented 5 years ago

I don't think class_alias should be supported, this function can take variables and it's impossible to determinate true name in many cases. Similar thing was with variable variables and now there is one check less https://github.com/bmewburn/vscode-intelephense/issues/445 If you really need class alias you should go for use MyClass as MyAlias;.

Sumanai commented 5 years ago

I think you can make support for aliases in simple cases with constant strings. I am codding stubs that connect to the workspace, and therefore the variant with use does not suit me. The extends variant basically works, but I'm not sure of its semantic identity with the class_alias function. Unfortunately, the product to which I write my stubs (1c-bitrix) is replete with antipatterns and compatibility layers, so I have to stick to it ((

bmewburn commented 5 years ago

Support for class_alias may help in cases like #700. It would be useful as a way to provide metadata where complex autoload scripts are used to resolve classes.

KapitanOczywisty commented 5 years ago

Support for class_alias may help in cases like #700.

Have you seen there class_alias? :smile: Prestashop has some autoload magic for what I can tell and I'm pretty sure sublime text has some exception to handle that.

However I can see why this could be useful so ignore my previous comment.

m50 commented 4 years ago

If I may add another example of usefulness for this: Facade aliases in Laravel (Proper support for facades would be nice, but that should be a separate entry altogether).

Laravel has a bunch of Facade aliases such as DB and Validator. And while you can import the full namespace, it can be handy for replaceable functionality later on. For example, if I just import the DB facade, and I want to swap it out with my own implementation that is compatible, I can without breaking the underlying Facade, just by pointing the alias to something else.

kczx3 commented 4 years ago

This would be useful for me as well. We use a super unknown framework that in its v1 form used global classes without namespaces. The v2 of it now makes use of namespaces but globalizes all of them using class_alias to help with migrating userland code to stop relying on the global classes. Some day we will be fully moved over to using them but that day is not today 😄

joe-scotto commented 4 years ago

I'm going to second what @m50 said. It would be helpful if Facades/Aliases worked.

beingmohit commented 4 years ago

+1

lumenpink commented 4 years ago

Yes! I vote for it too!

swashata commented 4 years ago

Yes please. I can mention one very important use case for WordPress test libraries. There we have something like

if ( class_exists( 'PHPUnit\Runner\Version' ) && version_compare( PHPUnit\Runner\Version::id(), '6.0', '>=' ) ) {

    class_alias( 'PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase' );
    class_alias( 'PHPUnit\Framework\Exception', 'PHPUnit_Framework_Exception' );
    class_alias( 'PHPUnit\Framework\ExpectationFailedException', 'PHPUnit_Framework_ExpectationFailedException' );
    class_alias( 'PHPUnit\Framework\Error\Deprecated', 'PHPUnit_Framework_Error_Deprecated' );
    class_alias( 'PHPUnit\Framework\Error\Notice', 'PHPUnit_Framework_Error_Notice' );
    class_alias( 'PHPUnit\Framework\Error\Warning', 'PHPUnit_Framework_Error_Warning' );
    class_alias( 'PHPUnit\Framework\Test', 'PHPUnit_Framework_Test' );
    class_alias( 'PHPUnit\Framework\Warning', 'PHPUnit_Framework_Warning' );
    class_alias( 'PHPUnit\Framework\AssertionFailedError', 'PHPUnit_Framework_AssertionFailedError' );
    class_alias( 'PHPUnit\Framework\TestSuite', 'PHPUnit_Framework_TestSuite' );
    class_alias( 'PHPUnit\Framework\TestListener', 'PHPUnit_Framework_TestListener' );
    class_alias( 'PHPUnit\Util\GlobalState', 'PHPUnit_Util_GlobalState' );
    class_alias( 'PHPUnit\Util\Getopt', 'PHPUnit_Util_Getopt' );

    class PHPUnit_Util_Test {

        // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
        public static function getTickets( $class_name, $method_name ) {
            $annotations = PHPUnit\Util\Test::parseTestMethodAnnotations( $class_name, $method_name );

            $tickets = array();

            if ( isset( $annotations['class']['ticket'] ) ) {
                $tickets = $annotations['class']['ticket'];
            }

            if ( isset( $annotations['method']['ticket'] ) ) {
                $tickets = array_merge( $tickets, $annotations['method']['ticket'] );
            }

            return array_unique( $tickets );
        }

    }

}

Without getting over the debate of why WordPress is doing this, I think we can all benefit from intelephese if this feature is implemented.


Until it is implemented though, as a work-around create a file intelephense-alias.php anywhere in the project (which should never be included in the application) and put

// A little fix for intelephense
class PHPUnit_Framework_TestCase extends \PHPUnit\Framework\TestCase {}
class PHPUnit_Framework_Exception extends \PHPUnit\Framework\Exception {}
class PHPUnit_Framework_ExpectationFailedException extends \PHPUnit\Framework\ExpectationFailedException {}
class PHPUnit_Framework_Error_Deprecated extends \PHPUnit\Framework\Error\Deprecated {}
class PHPUnit_Framework_Error_Notice extends \PHPUnit\Framework\Error\Notice {}
class PHPUnit_Framework_Error_Warning extends \PHPUnit\Framework\Error\Warning {}
class PHPUnit_Framework_Test extends \PHPUnit\Framework\Test {}
class PHPUnit_Framework_Warning extends \PHPUnit\Framework\Warning {}
class PHPUnit_Framework_AssertionFailedError extends \PHPUnit\Framework\AssertionFailedError {}
class PHPUnit_Framework_TestSuite extends \PHPUnit\Framework\TestSuite {}
class PHPUnit_Framework_TestListener extends \PHPUnit\Framework\TestListener {}
class PHPUnit_Util_GlobalState extends \PHPUnit\Util\GlobalState {}
class PHPUnit_Util_Getopt extends \PHPUnit\Util\Getopt {}
mforkel commented 3 years ago

+1

manao-dev commented 3 years ago

+1

handhikadj commented 2 years ago

+1

on https://github.com/googleapis/google-api-php-client-services , class_alias is used to provide backwards compatibility example: https://github.com/googleapis/google-api-php-client-services/blob/main/src/AIPlatformNotebooks/AcceleratorConfig.php

tacsipacsi commented 1 year ago

MediaWiki also makes heavy use of class_aliases in classes that have been namespaced to maintain backward compatibility. These class_alias calls cannot be replaced by use ... as ... statements, as the very goal of these aliases is that code using the class (which may be in another repo or even out of MediaWiki core developers’ control) doesn’t need to be touched, only code defining the class.

FMCorz commented 1 year ago

+1

tranductam2802 commented 1 year ago

+1

ntq-dongnv commented 1 year ago
alexdawn commented 5 months ago

I don't think class_alias should be supported, this function can take variables and it's impossible to determinate true name in many cases. Similar thing was with variable variables and now there is one check less #445 If you really need class alias you should go for use MyClass as MyAlias;.

This type of alias is not suitable when working on incrementally refactoring legacy code without namespaces to use namespaces. class_alias() allows us to move a class to a namespace while retaining a deprecated name in the global namespace so we don't have to insert 100s of use New\Namespace\MyClass as MyClass across the old code.

+1 for support for class_alias()