OpenPeeDeeP / depguard

Go linter that checks if package imports are in a list of acceptable packages.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.

So, Looking at #14 it could be done in a backwards compatable way, but I wonder if it is time to go to a version 2? That way it has a cleaner configuration, supports #14 and then we can define what items that you have above may be?

@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