type and method level blacklisting
frioux opened this issue · comments
I would like to submit a pull request that allows users to blacklist parts of packages, like certain functions, certain types, or methods on certain types. I think the config would gain six extra config sections:
functions
functionErrorMessages
types
typeErrorMessages
methods
methodErrorMessages
Would you be willing to accept such a patch?
My only stipulation, should not affect users who do not want these features (don't set them in configs). I am unsure what kind of performance hit it would be if we are reading more than just the import. I should only read the import if none of these are given. I would be gladly consider the PR though.
yeah, definitely possible. I'll start off with a PR for function support and we can get that merged, and then do the other two, since I suspect any issues you have will be the same with all three option sets.
@frioux Any update or progress on this issue?
I think this is out of scope of depguard. Working on V2 to resolve other issues that have come up. It may eventually get there, but with the other issues, this seems a bit out of reach at the moment.
I would find this very useful.
I checked and it would be a matter of walking the ast tree and looking for ast.CallExpr
structs for function calls. There will be other structs for functions as values, variable references, etc.
It poses a certain challenge because the ast is subject to change, so it must be updated with each go version. Or a more brute-force but future-proof approach would be using reflection to find the interesting nodes in the ast tree, independently of where they are. I have written a proof-of-concept for the later and it seems to work.
Shall I give it a stab and open a PR?
Update: I spent a bit more time and it's more difficult than it seemed to me originally.
The AST does not contain type information yet, so what you get is literally what's written in the source file (for example for an expression like time.Now().Add(2*time.Second)
you get something like time
+ Now
+ Add
+ ...), so it's not possible, for example, to tell what time
is (is it the time
package? is it another package like github.com/whatever/time
? or maybe a type alias? or a variable?), and likewise for time.Now()
we can't tell what type that is without actually going to check the time
package. So the whole type resolution is unavailable at this point.
I checked the go compiler and it looks like this logic is handled in cmd/compile/internal/types2
, which I don't think is a good idea to use, given it's internal. So, unless there are other ideas, I think I got to a dead end. (but what a fun ride!)
More info: https://go.dev/src/cmd/compile/README
FYI, I found another linter that partially does this. Works for my use case: https://github.com/ashanbrown/forbidigo