Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 291711

[Meta] Implement strict typing in existing code

$
0
0

PHP 7 introduces (return and scalar parameter) type declarations. In #2928856: Adopt the PSR-12 standard for PHP7 return types once Drupal 8 drops PHP 5 support there is discussion going on about adopting the PSR-12 standard for using return type declarations. However, as noted by drunken monkey implementing type hints in existing code in any form would be a breaking change.

The problem comes down to the fact that introducing type-hints in code that is used will make PHP complain that the contract isn't properly implemented by extending objects (see example 1). Implementing the type hints ahead of time does not break but produces warning because the extending case may be stricter (so not drop-in compatible) than the extended object (see example 2).

Issue #2928856: Adopt the PSR-12 standard for PHP7 return types once Drupal 8 drops PHP 5 support talks about implementing type declarations for new code. However, this still leaves us with a large codebase where the power of strict typing is not yet used to catch bugs ahead of time. The issues mentioned above means that changes both ways will be considered BC breaking and will need to happen in a major update.

Introducing this in a major update will make the update experience more difficult because more code needs to be changed at the same time. However, this jump will have to be made at some point if we want to let Drupal take advantage of the benefits that type hints bring.

Examples

Example 1

Adding type-hints in code that is extended without adding code to those extensions is problematic.


class Base {
    public function foo(int $x) : array {
        return [];
    }
}

class Child extends Base {
    public function foo($x) {
        return ["array"];
    }
}

$c = new Child();

echo $c->foo("bar");

Produces:
Fatal error: Declaration of Child::foo($x) must be compatible with Base::foo(int $x): array in [...][...] on line 13

Example 2

The opposite is also sort-of true, introducing type hints when the extended object has not already done so produces warning.


class Base {
    public function foo($x) {
        return [];
    }
}

class Child extends Base {
    public function foo(string $x) : string {
        return "great " . $x;
    }
}

$c = new Child();

echo $c->foo("bar");

Warning: Declaration of Child::foo(string $x): string should be compatible with Base::foo($x) in [...][...] on line 13

Proposed Solution

One saving grace that we have is that our coding standards already tell us to use PHPDoc type declarations all over Drupal. This means that we could use (an improved version of) a tool such as https://github.com/dunglas/phpdoc-to-typehint. Building this tool means that it can be used to convert Drupal core (possibly in reviewable chunks as sub-tasks of this issue) as well as contrib modules. It can then also be used for any downstream dependencies that we utilise.

I believe now is a good time to open this discussion if we want to see whether this is a feasible "big bang" step for Drupal 9.0 or whether we can do this in Drupal 10.0 not too long after.


Viewing all articles
Browse latest Browse all 291711

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>