diff options
author | David Malcolm <dmalcolm@redhat.com> | 2015-11-20 01:26:00 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2015-11-20 01:26:00 +0000 |
commit | 8ece8dfbd9cf38e10e0266ed22ead5bb389d8125 (patch) | |
tree | 3572616c35cc69549b3ff9761e6d1af8fb70780b /gcc/spellcheck-tree.c | |
parent | 32c912aad1f29233f15da6baf33c765e3b6213fd (diff) | |
download | gcc-8ece8dfbd9cf38e10e0266ed22ead5bb389d8125.zip gcc-8ece8dfbd9cf38e10e0266ed22ead5bb389d8125.tar.gz gcc-8ece8dfbd9cf38e10e0266ed22ead5bb389d8125.tar.bz2 |
C++ FE: offer suggestions for misspelled field names
gcc/c/ChangeLog:
* c-typeck.c (lookup_field_fuzzy): Move determination of closest
candidate into a new function, find_closest_identifier.
gcc/cp/ChangeLog:
* cp-tree.h (lookup_member_fuzzy): New decl.
* search.c: Include spellcheck.h.
(class lookup_field_fuzzy_info): New class.
(lookup_field_fuzzy_info::fuzzy_lookup_fnfields): New.
(lookup_field_fuzzy_info::fuzzy_lookup_field): New.
(lookup_field_fuzzy_r): New.
(lookup_member_fuzzy): New.
* typeck.c (finish_class_member_access_expr): When issuing
a "has no member named" error, call lookup_member_fuzzy, and
offer any result as a suggestion.
gcc/ChangeLog:
* spellcheck-tree.c (find_closest_identifier): New function, taken
from c/c-typeck.c:lookup_field_fuzzy, with NULL corrected to
NULL_TREE in two places.
* spellcheck.h (find_closest_identifier): New decl.
gcc/testsuite/ChangeLog:
* g++.dg/spellcheck-fields.C: New file.
From-SVN: r230638
Diffstat (limited to 'gcc/spellcheck-tree.c')
-rw-r--r-- | gcc/spellcheck-tree.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/gcc/spellcheck-tree.c b/gcc/spellcheck-tree.c index d203776..f7fbcc0 100644 --- a/gcc/spellcheck-tree.c +++ b/gcc/spellcheck-tree.c @@ -37,3 +37,44 @@ levenshtein_distance (tree ident_s, tree ident_t) IDENTIFIER_POINTER (ident_t), IDENTIFIER_LENGTH (ident_t)); } + +/* Given TARGET, an identifier, and CANDIDATES, a vec of identifiers, + determine which element within CANDIDATES has the lowest edit + distance to TARGET. If there are multiple elements with the + same minimal distance, the first in the vector wins. + + If more than half of the letters were misspelled, the suggestion is + likely to be meaningless, so return NULL_TREE for this case. */ + +tree +find_closest_identifier (tree target, const auto_vec<tree> *candidates) +{ + gcc_assert (TREE_CODE (target) == IDENTIFIER_NODE); + + int i; + tree identifier; + tree best_identifier = NULL_TREE; + edit_distance_t best_distance = MAX_EDIT_DISTANCE; + FOR_EACH_VEC_ELT (*candidates, i, identifier) + { + gcc_assert (TREE_CODE (identifier) == IDENTIFIER_NODE); + edit_distance_t dist = levenshtein_distance (target, identifier); + if (dist < best_distance) + { + best_distance = dist; + best_identifier = identifier; + } + } + + /* If more than half of the letters were misspelled, the suggestion is + likely to be meaningless. */ + if (best_identifier) + { + unsigned int cutoff = MAX (IDENTIFIER_LENGTH (target), + IDENTIFIER_LENGTH (best_identifier)) / 2; + if (best_distance > cutoff) + return NULL_TREE; + } + + return best_identifier; +} |