@@ -96,6 +96,11 @@ PartOfSpeech swift::getPartOfSpeech(StringRef word) {
96
96
return PartOfSpeech::Unknown;
97
97
}
98
98
99
+ // / Whether the given word is a plural s
100
+ static bool isPluralSuffix (StringRef word) {
101
+ return word == " s" || word == " es" || word == " ies" ;
102
+ }
103
+
99
104
void WordIterator::computeNextPosition () const {
100
105
assert (Position < String.size () && " Already at end of string" );
101
106
@@ -118,7 +123,20 @@ void WordIterator::computeNextPosition() const {
118
123
// If we hit the end of the string, that's it. Otherwise, this
119
124
// word ends before the last uppercase letter if the next word is alphabetic
120
125
// (URL_Loader) or after the last uppercase letter if it's not (UTF_8).
121
- NextPosition = (i == n || !clang::isLowercase (String[i])) ? i : i-1 ;
126
+
127
+ // Collect the lowercase letters up to the next word.
128
+ unsigned endOfNext = i;
129
+ while (endOfNext < n && clang::isLowercase (String[endOfNext]))
130
+ ++endOfNext;
131
+
132
+ // If the next word is a plural suffix, add it on.
133
+ if (i == n || isPluralSuffix (String.slice (i, endOfNext)))
134
+ NextPosition = endOfNext;
135
+ else if (clang::isLowercase (String[i]))
136
+ NextPosition = i-1 ;
137
+ else
138
+ NextPosition = i;
139
+
122
140
NextPositionValid = true ;
123
141
return ;
124
142
}
@@ -140,9 +158,19 @@ void WordIterator::computePrevPosition() const {
140
158
while (i > 0 && !clang::isUppercase (String[i-1 ]) && String[i-1 ] != ' _' )
141
159
--i;
142
160
161
+ // If what we found is a plural suffix, keep going.
162
+ bool skippedPluralSuffix = false ;
163
+ unsigned effectiveEndPosition = Position;
164
+ if (i > 0 && isPluralSuffix (String.slice (i, Position))) {
165
+ skippedPluralSuffix = true ;
166
+ effectiveEndPosition = i;
167
+ while (i > 0 && !clang::isUppercase (String[i-1 ]) && String[i-1 ] != ' _' )
168
+ --i;
169
+ }
170
+
143
171
// If we found any lowercase letters, this was a normal camel case
144
172
// word (not an acronym).
145
- if (i < Position ) {
173
+ if (i < effectiveEndPosition ) {
146
174
// If we hit the beginning of the string, that's it. Otherwise, this
147
175
// word starts with an uppercase letter if the next word is alphabetic
148
176
// (URL_Loader) or after the last uppercase letter if it's not (UTF_8).
@@ -577,6 +605,14 @@ static StringRef omitNeedlessWords(StringRef name,
577
605
auto newShortenedNameWord
578
606
= omitNeedlessWords (shortenedNameWord, typeName.CollectionElement ,
579
607
NameRole::Partial, allPropertyNames, scratch);
608
+ if (shortenedNameWord == newShortenedNameWord &&
609
+ shortenedNameWord.back () == ' e' ) {
610
+ shortenedNameWord.drop_back ();
611
+ newShortenedNameWord =
612
+ omitNeedlessWords (shortenedNameWord, typeName.CollectionElement ,
613
+ NameRole::Partial, allPropertyNames, scratch);
614
+ }
615
+
580
616
if (shortenedNameWord != newShortenedNameWord) {
581
617
matched ();
582
618
unsigned targetSize = newShortenedNameWord.size ();
@@ -749,11 +785,6 @@ static StringRef omitNeedlessWords(StringRef name,
749
785
return name;
750
786
}
751
787
752
- // / Whether the given word is a plural s
753
- static bool isPluralSuffix (StringRef word) {
754
- return word == " s" || word == " es" || word == " ies" ;
755
- }
756
-
757
788
StringRef camel_case::toLowercaseInitialisms (StringRef string,
758
789
StringScratchSpace &scratch) {
759
790
if (string.empty ())
@@ -834,8 +865,7 @@ static bool wordConflictsAfterPreposition(StringRef word,
834
865
// / Split the base name after the last preposition, if there is one.
835
866
static bool splitBaseNameAfterLastPreposition (StringRef &baseName,
836
867
StringRef &argName,
837
- const OmissionTypeName ¶mType,
838
- StringScratchSpace &scratch) {
868
+ const OmissionTypeName ¶mType) {
839
869
// Scan backwards for a preposition.
840
870
auto nameWords = camel_case::getWords (baseName);
841
871
auto nameWordRevIter = nameWords.rbegin (),
@@ -928,8 +958,7 @@ static bool splitBaseNameAfterLastPreposition(StringRef &baseName,
928
958
}
929
959
930
960
// Update the argument label and base name.
931
- argName = toLowercaseInitialisms (baseName.substr (startOfArgumentLabel),
932
- scratch);
961
+ argName = baseName.substr (startOfArgumentLabel);
933
962
baseName = newBaseName;
934
963
935
964
return true ;
@@ -938,8 +967,7 @@ static bool splitBaseNameAfterLastPreposition(StringRef &baseName,
938
967
// / Split the base name, if it makes sense.
939
968
static bool splitBaseName (StringRef &baseName, StringRef &argName,
940
969
const OmissionTypeName ¶mType,
941
- StringRef paramName,
942
- StringScratchSpace &scratch) {
970
+ StringRef paramName) {
943
971
// If there is already an argument label, do nothing.
944
972
if (!argName.empty ()) return false ;
945
973
@@ -962,7 +990,7 @@ static bool splitBaseName(StringRef &baseName, StringRef &argName,
962
990
return false ;
963
991
964
992
// Try splitting after the last preposition.
965
- if (splitBaseNameAfterLastPreposition (baseName, argName, paramType, scratch ))
993
+ if (splitBaseNameAfterLastPreposition (baseName, argName, paramType))
966
994
return true ;
967
995
968
996
return false ;
@@ -1042,8 +1070,7 @@ bool swift::omitNeedlessWords(StringRef &baseName,
1042
1070
1043
1071
// If needed, split the base name.
1044
1072
if (!argNames.empty () &&
1045
- splitBaseName (baseName, argNames[0 ], paramTypes[0 ], firstParamName,
1046
- scratch))
1073
+ splitBaseName (baseName, argNames[0 ], paramTypes[0 ], firstParamName))
1047
1074
anyChanges = true ;
1048
1075
1049
1076
// Omit needless words based on parameter types.
0 commit comments