report a local variable as the misspelling if there any many occourances of the global

This commit is contained in:
Erik Krogh Kristensen
2020-04-17 11:25:23 +02:00
parent 964a619450
commit 427c32f211
3 changed files with 56 additions and 5 deletions

View File

@@ -14,6 +14,37 @@
import Misspelling
from GlobalVarAccess gva, VarDecl lvd
where misspelledVariableName(gva, lvd)
select gva, "'" + gva + "' may be a typo for variable $@.", lvd, lvd.getName()
/**
* Gets the number of times a local variable with name `name` occurs in the program.
*/
bindingset[name]
int localAcceses(string name) {
result = count(VarAccess acc | acc.getName() = name and not acc instanceof GlobalVarAccess)
}
/**
* Gets the number of times a global variable with name `name` occurs in the program.
*/
bindingset[name]
int globalAccesses(string name) { result = count(GlobalVarAccess acc | acc.getName() = name) }
/**
* Holds if our heuristic says that the local variable `lvd` seems to be a misspelling of the global variable `gvd`.
* Otherwise the global variable is likely the misspelling.
*/
predicate globalIsLikelyCorrect(GlobalVarAccess gva, VarDecl lvd) {
// If there are more occurrences of the global (by a margin of at least 2), and the local is missing one letter compared to the global.
globalAccesses(gva.getName()) >= localAcceses(lvd.getName()) + 2 and
lvd.getName().length() = gva.getName().length() - 1
or
// Or if there are many more of the global.
globalAccesses(gva.getName()) > 2 * localAcceses(lvd.getName()) + 2
}
from GlobalVarAccess gva, VarDecl lvd, string msg
where
misspelledVariableName(gva, lvd) and
if globalIsLikelyCorrect(gva, lvd)
then msg = "$@ may be a typo for '" + gva + "'."
else msg = "'" + gva + "' may be a typo for variable $@."
select gva, msg, lvd, lvd.getName()