-
Notifications
You must be signed in to change notification settings - Fork 1.1k
add ContaintsStmts interface to mark stmt classes with nested stmts inside #1113
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
base: master
Are you sure you want to change the base?
Conversation
a0325e3
to
013f2d2
Compare
@TomasVotruba just for note: we have custom node: |
Is this actually useful to you if it does not include ClassMethod? |
It's very useful, as instead of 18 nodes types we can check single one. Also, the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TryCatch_
is also needs implemens Node\ContainsStmts
, see
use PhpParser\Node\PropertyItem; | ||
|
||
abstract class ClassLike extends Node\Stmt { | ||
abstract class ClassLike extends Node\Stmt implements Node\ContainsStmts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ClassLike
doesn't necessarily implemens Node\ContainsStmts
, we don't use ClassLike
to implements StmtsAwareInterface
which usually for remove/add logic, see comparison at
https://github.com/rectorphp/vendor-patches/tree/main/patches
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get this part, don't classes have stmts
as well? Or is the point here that the contents of Class_::$stmts
are not "normal" statements, so they should not be covered by this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikic for ClassLike, we usually don't loop to get target stmt, just use existing getMethod()
, getProperty()
.
The Smts interface is usually to check loop, then verify inner stmts instance, to append/remove node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikic Or is the point here that the contents of Class_::$stmts are not "normal" statements, so they should not be covered by this?
Exactly, they should not be covered here. The ClassLike
have $stmts
property, but Property
, ClassMethod
, ClassConst
etc. only wrap other $stmts
we really want to work with.
@TomasVotruba imo, public function getNodeTypes(): array
{
- return [StmtsAwareInterface::class];
+ return [Node\ContainsStmts::class, ClassMethod::class];
} for example, this required when we need to use it in required node, eg: downgrade rules which required code needs to be downgraded. we need also effort to update to include If the
interface ContainsStmts {}
// BC break patch, can be placed in our `bootstrap.php`
class_alias(ContainsStmts::class, \Rector\Contract\PhpParser\Node\StmtsAwareInterface::class);
class SomeNode implements ContainsStmts {}
$obj = new SomeNode();
// old should keep working
var_dump($obj instanceof \Rector\Contract\PhpParser\Node\StmtsAwareInterface);
// new
var_dump($obj instanceof ContainsStmts);
-final class FileWithoutNamespace extends Stmt implements StmtsAwareInterface
+final class FileWithoutNamespace extends Stmt implements Node\ContainsStmts
|
A way to include ClassMethod would be to give this a |
@nikic That sounds good. I think |
@TomasVotruba |
@samsonasik I agree. It was just example of such method :) |
|
||
$this->assertTrue($method->returnsByRef()); | ||
$this->assertNull($method->getStmts()); | ||
$this->assertSame([], $method->getStmts()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikic Not sure if should be a BC break.
In Rector we use $node->stmts === null
check to avoid foreach on null
errors. So if this will turn into []
, there is no real change.
@nikic I'm testing the interface and There is one issue with writing the modified $stmts = $if->getStmts();
foreach ($stmts as $key => $value) {
if (mt_rand(0, 1) {
// remove, add or shuffle nodes here
unset($stmts[$key]));
}
}
// then we want to update stmts array in the main node
$node->setStmts($stmts); Logical approach is to add /**
* @param Stmt[] $stmts
*/
public function setStmts(array $stmts): void
{
$this->stmts = $stmts;
} Thoughts? |
@TomasVotruba imo, For apply change, use direct That's why I suggest to add: /**
* @property Stmt[]|null $stmts
*/ tag in the interface before #1113 (review) that will also make less noise on phpstan/psalm check, avoid property not exists notice. |
This PR is revision #836 to address only mentioned issue with the
ClassMethod
.It's the only node, that can have
$stmts = null
value. Such method can beabstract
or part ofInterface_
, so there is nothing to iterate on. This revision exclude theClassMethod
This would solve run custom Rector tests on PHPUnit 12, remove lot of vendor patching in Rector
/vendor
(ugly hack), make make writing PHPStan rules for all nodes that have$stmts
easier and streamline working with the$stmts
property in userland