Skip to content

Please, make it easier to add new rules #14

@snosov1

Description

@snosov1

Hi!

In a pretty recent thread Mr. Bright complains about the number of compilation errors in a 2 years old D code base. A perfect answer to him would be "Please, run dfix on the code base and you're done". However, currently, dfix is not in shape to solve the problem.

But the saddest part is that the dfix solution is completely ignored by most of the people in the thread. They're not talking like "We should implement more rules in dfix", but rather argue about git log -S solutions and similar unstructured approaches.

I wanted to try and make a positive change in that thread by stating something like - "Hey, I've just made a pull request with a rule to dfix that changes all the occurences of 'fnmatch' with 'globMatch'". I expected this to be rather trivial, because it is indeed pretty easy to come up with a "grep"-based, for example.

However, looking at the code now, I don't have a clue how to do that. Not only there's no documentation on how to add new rules, but you can't really figure this out looking at the code as well.

Probably, this is the main reason why dfix is not catching up. If adding a rule for something like fnmatch->globMatch change would be as trivial as adding a 10-lines function, then making a code-breaking change to Phobos or compiler without adding this rule could be considered a public crime.

So, I wonder, is restructuring the code to a better shape and providing a documentation on adding new rules is it too much to ask?

P.S. Probably, you've heard of flint - a C++ linting tool written in D from Facebook, that was open-sourced by Andrei some time ago. I think it makes a good example of similar "rule"-based software. Consider a simple rule https://github.com/facebook/flint/blob/master/Checks.d#L476

uint checkBlacklistedIdentifiers(const string fpath, const CppLexer.Token[] v) {
  uint result = 0;

  string[string] banned = [
    "strtok" :
      "strtok() is not thread safe, and has safer alternatives.  Consider "
      "folly::split or strtok_r as appropriate.\n"
  ];

  foreach (ref t; v) {
    if (t.type_ != tk!"identifier") continue;
    auto mapIt = t.value_ in banned;
    if (!mapIt) continue;
    lintError(t, *mapIt);
    ++result;
  }

  return result;
}    

The code is so straightforward, you don't even need a documentation for it.

Granted, modifying the code can be a lot trickier, then just examining it, but at least simple things like fnmatch->globMatch can be made a lot easier (I think). And as Walter points out in the thread, even those simple things can make a big difference.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions