Skip to content

Commit 2b63e66

Browse files
committed
Support extracting Optional/ImplicitlyUnwrapped optional in Swift. And extracting only enum constant (exclude method, property, and so on).
1 parent a51cda9 commit 2b63e66

File tree

1 file changed

+90
-3
lines changed

1 file changed

+90
-3
lines changed

SCXcodeSwitchExpander/DVTTextCompletionController+SCXcodeSwitchExpander.m

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,78 @@
2222

2323
#import <objc/objc-class.h>
2424

25+
/// Returns symbol names from swift style full symbol name (e.g. from `Mirror.DisplayStyle` to `[Mirror, DisplayStyle]`).
26+
NSArray<NSString*>* symbolNamesFromFullSymbolName(NSString* fullSymbolName);
27+
28+
/// Returns normalized symbol name for -[IDEIndex allSymbolsMatchingName:kind:].
29+
NSString* normalizedSymbolName(NSString* symbolName);
30+
31+
/// Returns a symbol name removed swift generic parameter (e.g. `SomeType<T>` to `SomeType`).
32+
NSString* symbolNameRemovingGenericParameter(NSString* symbolName);
33+
34+
/// Returns a symbol name replaced syntax suggered optional to formal type name type in Swift (e.g. `Int?` to `Optional).
35+
NSString* symbolNameReplacingOptionalName(NSString* symbolName);
36+
37+
NSArray<NSString*>* symbolNamesFromFullSymbolName(NSString* fullSymbolName)
38+
{
39+
NSMutableArray<NSString*> *names = [[fullSymbolName componentsSeparatedByString:@"."] mutableCopy];
40+
41+
for (NSInteger nameIndex = 0; nameIndex != names.count; ++nameIndex)
42+
{
43+
names[nameIndex] = normalizedSymbolName(names[nameIndex]);
44+
}
45+
46+
return [names copy];
47+
}
48+
49+
NSString* normalizedSymbolName(NSString* symbolName)
50+
{
51+
NSString *result = symbolName;
52+
53+
result = symbolNameRemovingGenericParameter(result);
54+
result = symbolNameReplacingOptionalName(result);
55+
56+
return result;
57+
}
58+
59+
NSString* symbolNameRemovingGenericParameter(NSString* symbolName)
60+
{
61+
if ([[SCXcodeSwitchExpander sharedSwitchExpander] isSwift])
62+
{
63+
return [symbolName stringByReplacingOccurrencesOfString:@"<[^>]+>$"
64+
withString:@""
65+
options:NSRegularExpressionSearch
66+
range:NSMakeRange(0, symbolName.length)];
67+
}
68+
else
69+
{
70+
return symbolName;
71+
}
72+
}
73+
74+
NSString* symbolNameReplacingOptionalName(NSString* symbolName)
75+
{
76+
if ([[SCXcodeSwitchExpander sharedSwitchExpander] isSwift])
77+
{
78+
if ([symbolName hasSuffix:@"?"])
79+
{
80+
return @"Optional";
81+
}
82+
else if ([symbolName hasSuffix:@"!"])
83+
{
84+
return @"ImplicitlyUnwrappedOptional";
85+
}
86+
else
87+
{
88+
return symbolName;
89+
}
90+
}
91+
else
92+
{
93+
return symbolName;
94+
}
95+
}
96+
2597
@interface DVTTextCompletionListWindowController (SCXcodeSwitchExpander)
2698

2799
- (BOOL)tryExpandingSwitchStatement;
@@ -30,6 +102,11 @@ - (BOOL)tryExpandingSwitchStatement;
30102
- (NSArray<IDEIndexSymbol*>*)_getSymbolsByName:(NSString*)name fromCollection:(IDEIndexCollection*)collection;
31103
- (NSArray<IDEIndexSymbol*>*)_getSymbolsByNames:(NSArray<NSString*>*)names fromCollection:(IDEIndexCollection*)collection;
32104

105+
- (BOOL)isSymbolKindEnum:(DVTSourceCodeSymbolKind *)symbol;
106+
107+
/// Returns a boolean value whether `symbolKind` means a enum constant.
108+
- (BOOL)isSymbolKindEnumConstant:(DVTSourceCodeSymbolKind *)symbolKind;
109+
33110
@end
34111

35112
@implementation DVTTextCompletionController (SCXcodeSwitchExpander)
@@ -110,7 +187,7 @@ @implementation DVTTextCompletionListWindowController (SCXcodeSwitchExpander)
110187

111188
- (NSArray<IDEIndexSymbol*>*)getSymbolsByFullName:(NSString*)fullSymbolName fromIndex:(IDEIndex*)index
112189
{
113-
NSArray<NSString*> *names = [fullSymbolName componentsSeparatedByString:@"."];
190+
NSArray<NSString*> *names = symbolNamesFromFullSymbolName(fullSymbolName);
114191
IDEIndexCollection *collection = [index allSymbolsMatchingName:names.firstObject kind:nil];
115192

116193
return [self findSymbolsWithNames:names fromCollection:collection];
@@ -137,11 +214,9 @@ - (BOOL)tryExpandingSwitchStatement
137214
for(IDEIndexSymbol *symbol in symbols) {
138215

139216
DVTSourceCodeSymbolKind *symbolKind = symbol.symbolKind;
140-
NSLog(@"%@ (Kind=%@)", symbol.description, symbol.symbolKind);
141217

142218
BOOL isSymbolKindEnum = NO;
143219
for(DVTSourceCodeSymbolKind *conformingSymbol in symbolKind.allConformingSymbolKinds) {
144-
NSLog(@"%@", conformingSymbol.identifier);
145220
isSymbolKindEnum = [self isSymbolKindEnum:conformingSymbol];
146221
}
147222

@@ -230,6 +305,13 @@ - (BOOL)tryExpandingSwitchStatement
230305
}
231306

232307
for(IDEIndexSymbol *child in [((IDEIndexContainerSymbol*)symbol).children allObjects]) {
308+
309+
// skip the `child` symbol if it is not a enum constant.
310+
if (![self isSymbolKindEnumConstant:child.symbolKind])
311+
{
312+
continue;
313+
}
314+
233315
if([switchContent rangeOfString:child.displayName].location == NSNotFound) {
234316
if ([[SCXcodeSwitchExpander sharedSwitchExpander] isSwift]) {
235317
NSString *childDisplayName = [self correctEnumConstantIfFromCocoa:[NSString stringWithFormat:@"%@",symbol] symbolName:symbolName cocoaEnumName:child.displayName];
@@ -287,6 +369,11 @@ - (BOOL)isSymbolKindEnum:(DVTSourceCodeSymbolKind *)symbol
287369
return [symbol.identifier isEqualToString:@"Xcode.SourceCodeSymbolKind.Enum"];
288370
}
289371

372+
- (BOOL)isSymbolKindEnumConstant:(DVTSourceCodeSymbolKind *)symbolKind
373+
{
374+
return [symbolKind.identifier isEqualToString:@"Xcode.SourceCodeSymbolKind.EnumConstant"];
375+
}
376+
290377
- (NSUInteger)matchingBracketLocationForOpeningBracketLocation:(NSUInteger)location inString:(NSString *)string
291378
{
292379
if(string.length == 0) {

0 commit comments

Comments
 (0)