diff options
author | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-20 01:26:00 +0000 |
---|---|---|
committer | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-20 01:26:00 +0000 |
commit | 11d8dd6fe925464af9dc8283360e196c55c48e17 (patch) | |
tree | 3572616c35cc69549b3ff9761e6d1af8fb70780b /gcc/spellcheck-tree.c | |
parent | af44a72df6662100baea4ddfd36dc5fe945640ae (diff) | |
download | gcc-11d8dd6fe925464af9dc8283360e196c55c48e17.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230638 138bc75d-0d04-0410-961f-82ee72b054a4
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 d2037766eca..f7fbcc0be32 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; +} |