-
Notifications
You must be signed in to change notification settings - Fork 44
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
The Keyword Question #273
Comments
One possible solution that i can think of here, would be for PPI to be import-aware, in regards to keywords, and allow calling code to configure the parser to presume that based on [ module name string, module use regex, module use callback ] matches, certain keywords would be present in the attached block. That way we could define default sets [ core, cpan popular ], but still allow people with custom import modules to configure for their environment. Thoughts @adamkennedy @oalders @Grinnz @EvanCarroll ? |
|
Unfortunately my only conclusion on this is that PPI on its own cannot solve this. Chasing imports is a losing battle and would be a hack at best, literally any use statement or BEGIN block can arbitrarily change the parser state. I haven't thought of an alternative. |
I agree that there are problems which Having said that, I think there's a use case that says
I think in cases like these if If One of the places where I'd like to see improvements is in better Perl tooling, especially in my editor. Having |
I think solving for 90% of cases if it can be done in a useful manner without breaking the remaining 10% of cases should be a goal. Personally my worry with per-file-config without any import tracking whatsoever is that it makes it very hard to configure how and when to change parse modes if people have something as basic as files with different perl feature imports in the same project, or different imports for different blocks in a file. That's why i think chasing imports is more helpful than doing file-level parse mode declarations because it's easy to allow people to configure what imports do what, while also allowing the option of doing per-file configurations. |
👍🏻
To be clear, in my case, just a per-project config would cover most of my cases. At
Any thoughts on how you would want to go about this? |
I can give an example of how that would work with I believe a common pattern is to use which lets me know what keywords and parameters were used by |
The problem is that executing arbitrary code of any sort is not acceptable as a PPI implementation. |
That's true. If there is a plugin framework to support various keyword/keyword-like modules from CPAN, then at the very least they would need to have a way to configure which ones are loaded in a given file and with what settings. That should perhaps be a callback. PPI itself can not load the arbitrary code, but the user of PPI can decide if they want to return a static configuration or not. The parser would have to do multiple passes to get all the |
Yeah, i recognize the value, and maybe we should just do that to start off with and mark it highly experimental. My hesitation stems from having a large $work project with code that applies pragmas in like 40% of the files. :) Also i think it's better if PPI fails to parse something as a more complex form of what it seems to be, rather than succeeding in parsing a complex structure that is actually a mistake by the code's author and only looks like a complex thing it isn't. But i may be wrong on this.
As a general thought:
The specific contents of the callback can be left up in the air for now, but there's plenty options there, up to and including executing an arbitrary callback passed in by the user, making it a parse-hook, which if absolutely necessary, might also allow things such as what @zmughal suggested there i think. While i agree with @Grinnz that PPI itself will not execute the code it parses, i think an exception could be made for allowing users to define hooks that might execute parsed code. Hm. |
Edit: This also enables some interesting "parsing features" such as using PPI to determine which features are likely to be enabled or disabled, and maybe even based on that to ask PPI what the minimum Perl version for a block or a parsed document is. |
This is the solution that I would propose. This seems like a requirement. You're being more comprehensive by allowing other modules on CPAN to enable these options, but that's a step more than what I think is required for a minimal solution. You're given two options here,
I suggested Keywords over in #194 as just one method there but I don't see these at all as discrete questions.
Are all related to the same core problem. It's just a parsing problem. The parser should be viewed as a customizable thing which is subject to versioning and modifications with pragmas and not something we can make any sense of divorced of those pragmas. |
To repeat, literally any use statement or BEGIN statement can enable these parser changes without mentioning them. It is in fact extremely common due to modules like Moose and Mojolicious. |
this might need some consideration and thought in regards to what happens when the user changes the tree 😑 |
This isn't something I don't know; you're not telling me something new there. I addressed it explicitly. I just don't particularly care because,
Moreover,
It would seem preferable to me to support the methods that Perl supports to the best humanly possible. Including all pragmas that change parsing semantics, and to make modules which push an unsupported method of changing parsing semantics as second class citizens. Even if realistically we realistically can support them above it should never come at the expense of not supporting Perl functionality. You may never be able to support all second-class use cases (like CPAN), but if you can't support things documented and supported by Perl itself everything will suffer |
It's used by thousands of CPAN modules and almost every Darkpan project over a certain size. "support" isn't particularly relevant. |
I must admit i'm not entirely following the disagreement between the two of you. I think it's true that massive amounts of code use a lot of almost untrackable ways to enable features and keywords. I also think it's true that we can both make the parser aware of features, and able to automatically track (and particularly so with configuration) enough uses to make it worthwhile? |
Implementation-wise, i remembered that we are indeed operating with a tree, so:
|
To keep this documented: 18:54 we basically only need two things: |
I have implemented a proof-of-concept, please review and comment: #280 |
Closing this, since the POC in #280 is moving closer to being ready to be released. Comments on the specific implementation are very welcome. |
Edit: I have implemented a proof-of-concept, please review and comment: #280
This spawned from discussion in #194 and Perl-Critic/Perl-Critic#591
There are a lot of hard problems with Perl parsing that lead people to think there are simple answers, which leave out real problems. Here is a demonstration of not even how PPI parses things, but of how just by looking at code, it is impossible to predict what the Perl Parser itself will do.
strect.pm
legacy.pl
modern.pl
This demonstrates how in a plausible use case, the parsing of keywords can be affected even on the same interpreter, by something entirely outside the code itself, like command line arguments.
This is problematic because, depending on the imported keywords, this block:
is seen by the Perl Parser as either 1 statement (with try consuming the return value of the print), or 2 statements (try, followed by print).
NOTE ALSO: Some people might like to mentally short-circuit here with "just assume try is the modern form". That would be useless. I used try here for brevity and reproducability. Other modules might import other keywords.
And to top this off, here is an example within a single file:
stroct.pm
mixed.pl
This demonstrates how even within the same file, based on lexical imports with no sensible hints PPI could possibly predict,
try {} catch {} print 5;
might be one or two statements.The text was updated successfully, but these errors were encountered: