-
Notifications
You must be signed in to change notification settings - Fork 11
Description
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.