summaryrefslogtreecommitdiff
path: root/gcc/spellcheck-tree.c
diff options
context:
space:
mode:
authordmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-20 01:26:00 +0000
committerdmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-20 01:26:00 +0000
commit11d8dd6fe925464af9dc8283360e196c55c48e17 (patch)
tree3572616c35cc69549b3ff9761e6d1af8fb70780b /gcc/spellcheck-tree.c
parentaf44a72df6662100baea4ddfd36dc5fe945640ae (diff)
downloadgcc-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.c41
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;
+}