antecedent/patchwork

Feature request: insert `declare(ticks=1)` in every included file

rulatir opened this issue · 1 comments

As of PHP 7, declare(ticks=1) has file scope. Debugging strategies that rely on tickwalking entire codebases no longer work. A cursory stackoverflow search reveals that people are trying left and right to implement automatic insertion of declare(ticks=1) using stream wrappers, but all these attempts fail because writing stream wrappers is flat out NIGHTMARISHLY DIFFICULT. This project however seems to have the foundation in place, and I guess implementing this feature would be trivial for the author. Pretty please?

At present, I'm not convinced that this would be the right course of action. I argue that the alternative of reusing just the stream wrapper from this project is sufficiently easy to make the bifurcation of the project's scope seem unwarranted. However, this is merely how I've been feeling about this since you've raised this point, and I'd be happy to be convinced otherwise. 🙂

I detail the two parts of my argument below.

Reusing just the stream wrapper

The foundation that you mention is nothing else than Stream.php, which doesn't really depend on any other part of the codebase. By all means, feel free to reuse it.

For inserting declare(ticks=1); in the right place, just run token_get_all() and splice the declaration in after the first T_OPEN_TAG.

Alternatively, use nikic/php-parser.

Bifurcation of the project's scope

I don't really want Patchwork to become a library for "method redefinition and some other unrelated tasks that also happen to involve code preprocessing".

However, I can't also name any well-argued reason for that aside from a rather automatic instantiation of the Single Responsibility Principle. I imagine that the project would become less manageable, marketable and whatnot, but I might as well be mistaken for now.


Aside from the cost-benefit considerations being an open question, I wonder about possible compromises.

It would be really great to decompose the project into 2 subprojects: the code manipulator (stream wrapper + code parser + rewriter) and the call rerouter (monkey-patching-specific functionality). Then, I could adduce the declare(ticks=1);-propagation logic as another small project dependent on the code manipulator.

What are your thoughts on this?