|
14 | 14 |
|
15 | 15 | import Misspelling |
16 | 16 |
|
17 | | -from GlobalVarAccess gva, VarDecl lvd |
18 | | -where misspelledVariableName(gva, lvd) |
19 | | -select gva, "'" + gva + "' may be a typo for variable $@.", lvd, lvd.getName() |
| 17 | +/** |
| 18 | + * Gets the number of times a local variable with name `name` occurs in the program. |
| 19 | + */ |
| 20 | +bindingset[name] |
| 21 | +int localAcceses(string name) { |
| 22 | + result = count(VarAccess acc | acc.getName() = name and not acc instanceof GlobalVarAccess) |
| 23 | +} |
| 24 | + |
| 25 | +/** |
| 26 | + * Gets the number of times a global variable with name `name` occurs in the program. |
| 27 | + */ |
| 28 | +bindingset[name] |
| 29 | +int globalAccesses(string name) { result = count(GlobalVarAccess acc | acc.getName() = name) } |
| 30 | + |
| 31 | +/** |
| 32 | + * Holds if our heuristic says that the local variable `lvd` seems to be a misspelling of the global variable `gva`. |
| 33 | + * Otherwise the global variable is likely the misspelling. |
| 34 | + */ |
| 35 | +predicate globalIsLikelyCorrect(GlobalVarAccess gva, VarDecl lvd) { |
| 36 | + // 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. |
| 37 | + globalAccesses(gva.getName()) >= localAcceses(lvd.getName()) + 2 and |
| 38 | + lvd.getName().length() = gva.getName().length() - 1 |
| 39 | + or |
| 40 | + // Or if there are many more of the global. |
| 41 | + globalAccesses(gva.getName()) > 2 * localAcceses(lvd.getName()) + 2 |
| 42 | +} |
| 43 | + |
| 44 | +from GlobalVarAccess gva, VarDecl lvd, string msg |
| 45 | +where |
| 46 | + misspelledVariableName(gva, lvd) and |
| 47 | + if globalIsLikelyCorrect(gva, lvd) |
| 48 | + then msg = "$@ may be a typo for '" + gva + "'." |
| 49 | + else msg = "'" + gva + "' may be a typo for variable $@." |
| 50 | +select gva, msg, lvd, lvd.getName() |
0 commit comments