Skip to content

withImportNames: Creates imports which collide with PHP reserved class names #9190

@CharlemagneLasse

Description

@CharlemagneLasse

Bug Report

Subject Details
Rector version 2.0.16

If I run rector with the cassandra module, I end quite often with broken imports because ext-cassandra reuses names which are known in other modules (Set, Map, Exception, ...) or even in the main language (Float, ...). This is then shown as error:

PHP Fatal error:  Cannot use Cassandra\Float as Float because 'Float' is a special class name
Fatal error: Cannot use Cassandra\Float as Float because 'Float' is a special class name

See the php code for the currently recognized special class names:

struct reserved_class_name {
	const char *name;
	size_t len;
};
static const struct reserved_class_name reserved_class_names[] = {
	{ZEND_STRL("bool")},
	{ZEND_STRL("false")},
	{ZEND_STRL("float")},
	{ZEND_STRL("int")},
	{ZEND_STRL("null")},
	{ZEND_STRL("parent")},
	{ZEND_STRL("self")},
	{ZEND_STRL("static")},
	{ZEND_STRL("string")},
	{ZEND_STRL("true")},
	{ZEND_STRL("void")},
	{ZEND_STRL("never")},
	{ZEND_STRL("iterable")},
	{ZEND_STRL("object")},
	{ZEND_STRL("mixed")},
	/* These are not usable as class names because they're proper tokens,
	 * but they are here for class aliases. */
	{ZEND_STRL("array")},
	{ZEND_STRL("callable")},
	{NULL, 0}
};

static bool zend_is_reserved_class_name(const zend_string *name) /* {{{ */
{
	const struct reserved_class_name *reserved = reserved_class_names;

	const char *uqname = ZSTR_VAL(name);
	size_t uqname_len = ZSTR_LEN(name);
	zend_get_unqualified_name(name, &uqname, &uqname_len);

	for (; reserved->name; ++reserved) {
		if (uqname_len == reserved->len
			&& zend_binary_strcasecmp(uqname, uqname_len, reserved->name, reserved->len) == 0
		) {
			return 1;
		}
	}

	return 0;
}
/* }}} */

Minimal PHP Code Causing Issue

https://getrector.com/demo/f9591693-528c-4534-b029-752746a1f78e

Expected Behaviour

Rector should import things which are special class names. I would be also fine for me if there would be a mechanism which I could use to tell withImportNames to not use imports for \Cassandra or not \Cassandra\Float

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions