Comments (9)
And the issue is resolved! There was a problem when the same method was declared in both class and used trait. 6e3a590
So the dev-master now is what the traits support will look like in next stable version.
from phpstan.
The feedback PHPStan gives about your code is that it's easily breakable by using the trait by a wrong class. Take this code for example: https://3v4l.org/XQ0Y4
It will crash in runtime because you used the trait by a class without the doBar() method.
But consider this example: https://3v4l.org/F6W8K
This code won't even compile because you enforce in the trait that the target class must implement the doBar() method. The latter example is also something that PHPStan will be satisfied with.
So consider your codebase to adopt this approach to make it bullet-proof against wrong usage.
But your idea about a different approach to analysing traits is interesting and something to think about :) Thanks!
from phpstan.
@ondrejmirtes I still think that using abstract methods in traits is a hack. I like to solution proposed by @ahungry a lot more.
Another possible approach is to use @method
+ @property
annotations on trait and verify that the class using trait actually does have all the required methods and properties.
from phpstan.
from phpstan.
Thanks for the responses - I hadn't thought of using abstract method declarations in the trait (good idea for most traits). Unfortunately, this actual use case involves a class constant, which, while properly guarded in the trait itself with defined checks, doesn't propagate down to phpstan.
General sample code to illustrate how this may look (granted no one would really use this, but I digress...):
trait FooTrait
{
public function getFilePath(string $fileName): string
{
if (!defined('self::ASSET_PATH')) {
throw new Exception(
__CLASS__
. '::ASSET_PATH must be defined to use '
. __METHOD__
);
}
return realpath(self::ASSET_PATH . '/' . $fileName);
}
}
class Bar
{
use FooTrait;
const ASSET_PATH = '/tmp';
}
// Obviously ok
echo Bar::getFilePath('file.txt');
class Baz
{
use FooTrait;
}
// Throws the Exception as expected with message: PHP Fatal error: Uncaught
// Exception: Baz::ASSET_PATH must be defined to use FooTrait::getFilePath
echo Baz::getFilePath('file2.txt');
from phpstan.
I've prepared a pull request that updates the parsing process to handle traits under all their possible contexts.
I think this is better than annotations or abstracting in the trait.
Let me know what you think:
from phpstan.
Sorry for the poor formatting, I didn't realize there are tabs for indentation - I may have to make another PR to run emacs M-x untabify
across your codebase (half joking 😄 )
Edit: No idea what's going on with your Travis CI either - unit tests pass fine for me locally, but that process on Travis is getting a lot of errors when testing this PR.
from phpstan.
@JanTvrdik @ahungry Can you try out current master? I implemented the idea here: e59d160 (but use current dev-master
in composer because later commits also affect this behaviour).
If you're OK with the results I will release 0.5.
from phpstan.
It works fine according to your reactions here #23 (comment) but I still need to figure out one issue, hope to do that soon. But since you are satisifed with the current results, I will close this now. Thanks!
from phpstan.
Related Issues (20)
- `@param-out` has wrong expect value when open Bleeding edge HOT 1
- Class constant named 'class' not reported, but causes fatal error
- Trimming a numeric-string might also return a numeric-string HOT 6
- `@param-out` has varTag.type bug HOT 1
- Invalid array key for constant array append when negative keys are used since PHP 8.3
- False positive error on DateTime constructor for PHP 7.2-7.4 HOT 3
- Hint about the error identitier in `analyse` output HOT 2
- get_defined_vars() doesn't make function arguments considered used HOT 1
- Incorrect math and flow operation HOT 4
- Process error in just one file of 756 files: Name cannot be empty while analysing file /path/to/file/file.php HOT 5
- Changes to variables by includes not taken into account HOT 1
- PHPStan wrongly assumes that `$_SERVER` cannot be `null` HOT 2
- Cannot combine generic key types when `@template` is limited to `array-key`
- ConstantArrayType is not accepted into ConstantArrayType with the same description
- `@phpstan-type` should allow comment HOT 1
- Trait as method argument HOT 1
- Count after calling SplObjectStorage::removeAll
- Stub validation does not work in an extension HOT 3
- False positive on stream_get_meta_data HOT 4
- Incorrect `\Imagick::identifyImage()` return type HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from phpstan.