TLDR: Say you had to onboard a new team member of the Linter package: what tips and tricks would you share to help them get up to speed with writing lint rules most efficiently ?
I'm currently building a dev tool based on Analyzer, that use custom lint rules on Dart/Flutter code. I've been primarily working with the analyzer for over a year, have read all of the docs on writing custom rules in the analyzer_plugin, analyzer, and linter packages, and am mostly familiar with how the tool works in general.
When it comes to writing lint rules, I'm having a bit of trouble building a good mental model for creating AstNode-specific logic. Unlike other aspects of software development where I can “forsee” the logic before writing any code, for lint rules I build up coverage for rule use cases via an ad hoc TDD workflow, for example:
The above workflow has actually been working relatively well for me, and the new sealed class modifiers + exhaustiveness checking features have further helped me wrap my head around the inheritance model of certain AstNodes. But it all still feels a little too trial and error than what I’m used to, and I don't ever feel 100% certain that my rules have captured all edge cases.
As a concrete example, see the ARB Resource value parser attached. I’ve written several of these “Expression-agnostic” functions that use switch expressions to capture specific values of every type of Expression. While I do eventually find the commonalities of all of the different nodes in order to refactor a “more exhaustive” implementation, it's not that intuitive (yet, I suppose).
(see attached example file)
Anyways, some specific questions I've thought of:
Thanks in advance for any insight! It's greatly appreciated :)
I'm having a bit of trouble building a good mental model for creating AstNode-specific logic.
... I don't ever feel 100% certain that my rules have captured all edge cases.
Do certain patterns exist that are often used ? e.g. recursive expression evaluation, capturing variable declarations that match a given predicate
Is it possible to know with certainty if you've captured all use cases?
Is there another workflow that you'd recommend besides the aforementioned TDD approach?
is there a Discord server or similar forum for discussing analyzer tips and tricks with folks working on similar projects?
--
You received this message because you are subscribed to the Google Groups "Dart Analyzer Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to analyzer-discu...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/analyzer-discuss/efc3ea32-eda2-4c36-b1bf-39ba484954ccn%40dartlang.org.
And I disagree with Brian a bit, considering that the analyzer and the linter sometimes also have these problems of not covering some cases. So even with the experience it's still possible to make this mistake.
Do you have any design documents on how the AST can be improved? I'd love to take a look on that.
IMO, the vast majority of problems come from not really knowing all possible "parent -> child" relationships. And `AstNode? get parent;` is the main contributor to this confusion. If we could have an option of union types or at least of comments describing possible relationships, that would help a lot. Basically what @modulovalue has shown, but closer to the source code. But I do understand that supporting this documentation might be not worth it.
What do you mean by a "concrete suggestion" in this context? Do you need a list of nodes for which this documentation can be useful or something else?