Skip to content

Commit 74ba0fe

Browse files
committed
Support enum type implemented in class/struct extension in Swift.
1 parent 364bb1e commit 74ba0fe

File tree

5 files changed

+74
-59
lines changed

5 files changed

+74
-59
lines changed

SCXcodeSwitchExpander.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
18990B3618D2529C007A8756 /* SCXcodeSwitchExpander.m in Sources */ = {isa = PBXBuildFile; fileRef = 18990B3518D2529C007A8756 /* SCXcodeSwitchExpander.m */; };
1414
18A1B48118DDA742007CA06A /* IDEFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18A1B48018DDA742007CA06A /* IDEFoundation.framework */; };
1515
18ECEB5718D267A0005F6C59 /* DVTTextCompletionController+SCXcodeSwitchExpander.m in Sources */ = {isa = PBXBuildFile; fileRef = 18ECEB5618D267A0005F6C59 /* DVTTextCompletionController+SCXcodeSwitchExpander.m */; };
16+
B127B27C1CBBDDE000E32C2B /* IDEIndexClassSymbol.m in Sources */ = {isa = PBXBuildFile; fileRef = B127B27B1CBBDDE000E32C2B /* IDEIndexClassSymbol.m */; };
1617
B150FD8A1CBBD7D200DFE4D8 /* DVTTextCompletionSession+SCXcodeSwitchExpander.m in Sources */ = {isa = PBXBuildFile; fileRef = B150FD891CBBD7D200DFE4D8 /* DVTTextCompletionSession+SCXcodeSwitchExpander.m */; };
1718
B18173D81CBB91E400995105 /* DVTSourceCodeLanguage+SCXCodeSwitchExpander.m in Sources */ = {isa = PBXBuildFile; fileRef = B18173D71CBB91E400995105 /* DVTSourceCodeLanguage+SCXCodeSwitchExpander.m */; };
1819
/* End PBXBuildFile section */
@@ -43,6 +44,8 @@
4344
18A1B48018DDA742007CA06A /* IDEFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IDEFoundation.framework; path = ../../../../Applications/Xcode.app/Contents/Frameworks/IDEFoundation.framework; sourceTree = "<group>"; };
4445
18ECEB5518D267A0005F6C59 /* DVTTextCompletionController+SCXcodeSwitchExpander.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DVTTextCompletionController+SCXcodeSwitchExpander.h"; sourceTree = "<group>"; };
4546
18ECEB5618D267A0005F6C59 /* DVTTextCompletionController+SCXcodeSwitchExpander.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "DVTTextCompletionController+SCXcodeSwitchExpander.m"; sourceTree = "<group>"; };
47+
B127B27A1CBBDDE000E32C2B /* IDEIndexClassSymbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDEIndexClassSymbol.h; sourceTree = "<group>"; };
48+
B127B27B1CBBDDE000E32C2B /* IDEIndexClassSymbol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IDEIndexClassSymbol.m; sourceTree = "<group>"; };
4649
B150FD881CBBD7D200DFE4D8 /* DVTTextCompletionSession+SCXcodeSwitchExpander.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DVTTextCompletionSession+SCXcodeSwitchExpander.h"; sourceTree = "<group>"; };
4750
B150FD891CBBD7D200DFE4D8 /* DVTTextCompletionSession+SCXcodeSwitchExpander.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "DVTTextCompletionSession+SCXcodeSwitchExpander.m"; sourceTree = "<group>"; };
4851
B18173D61CBB91E400995105 /* DVTSourceCodeLanguage+SCXCodeSwitchExpander.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DVTSourceCodeLanguage+SCXCodeSwitchExpander.h"; sourceTree = "<group>"; };
@@ -82,6 +85,8 @@
8285
0144D99F1B06F9F00012D7A2 /* IDEEditor.h */,
8386
0144D9B11B06FBD30012D7A2 /* IDEFileTextSettings.h */,
8487
0144D9A01B06F9F00012D7A2 /* IDEIndex.h */,
88+
B127B27A1CBBDDE000E32C2B /* IDEIndexClassSymbol.h */,
89+
B127B27B1CBBDDE000E32C2B /* IDEIndexClassSymbol.m */,
8590
0144D9A11B06F9F00012D7A2 /* IDEIndexCollection.h */,
8691
0144D9A21B06F9F00012D7A2 /* IDEIndexCompletionItem.h */,
8792
0144D9A31B06F9F00012D7A2 /* IDEIndexContainerSymbol.h */,
@@ -210,6 +215,7 @@
210215
B150FD8A1CBBD7D200DFE4D8 /* DVTTextCompletionSession+SCXcodeSwitchExpander.m in Sources */,
211216
18990B3618D2529C007A8756 /* SCXcodeSwitchExpander.m in Sources */,
212217
B18173D81CBB91E400995105 /* DVTSourceCodeLanguage+SCXCodeSwitchExpander.m in Sources */,
218+
B127B27C1CBBDDE000E32C2B /* IDEIndexClassSymbol.m in Sources */,
213219
);
214220
runOnlyForDeploymentPostprocessing = 0;
215221
};

SCXcodeSwitchExpander/DVTTextCompletionController+SCXcodeSwitchExpander.m

Lines changed: 41 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
#import <objc/objc-class.h>
2828

29+
/// Returns namespace name by symbol's resolution.
30+
NSString* namespaceFromResolutionOfSymbol(IDEIndexSymbol* symbol);
31+
2932
/// Returns symbol names from swift style full symbol name (e.g. from `Mirror.DisplayStyle` to `[Mirror, DisplayStyle]`).
3033
NSArray<NSString*>* symbolNamesFromFullSymbolName(NSString* fullSymbolName, DVTSourceCodeLanguageKind language);
3134

@@ -38,6 +41,14 @@
3841
/// Returns a symbol name replaced syntax suggered optional to formal type name type in Swift (e.g. `Int?` to `Optional).
3942
NSString* symbolNameReplacingOptionalName(NSString* symbolName, DVTSourceCodeLanguageKind language);
4043

44+
45+
NSString* namespaceFromResolutionOfSymbol(IDEIndexSymbol* symbol)
46+
{
47+
NSString *resolution = symbol.resolution;
48+
49+
return [resolution stringByReplacingOccurrencesOfString:@"^s:\\w+16" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, resolution.length)];
50+
}
51+
4152
NSArray<NSString*>* symbolNamesFromFullSymbolName(NSString* fullSymbolName, DVTSourceCodeLanguageKind language)
4253
{
4354
NSMutableArray<NSString*> *names = [[fullSymbolName componentsSeparatedByString:@"."] mutableCopy];
@@ -113,18 +124,6 @@ @interface DVTTextCompletionListWindowController (SCXcodeSwitchExpander)
113124

114125
- (BOOL)tryExpandingSwitchStatementForLanguage:(DVTSourceCodeLanguageKind)language;
115126

116-
/// Returns symbols specified by `fullSymbolName` in Index.
117-
- (NSArray<IDEIndexSymbol*>*)getSymbolsByFullName:(NSString*)fullSymbolName forLanguage:(DVTSourceCodeLanguageKind)language fromIndex:(IDEIndex*)index;
118-
119-
/// Returns symbols that found in top `collection` by names recursively.
120-
- (NSArray<IDEIndexSymbol*>*)findSymbolsWithNames:(NSArray<NSString*>*)names fromCollection:(IDEIndexCollection*)collection;
121-
122-
/// Returns symbols named `name` in `collection`
123-
- (NSArray<IDEIndexSymbol*>*)_getSymbolsByName:(NSString*)name fromCollection:(IDEIndexCollection*)collection;
124-
125-
/// Returns symbols named `name[0].name[1].name[2]...` in `collection` recursively.
126-
- (NSArray<IDEIndexSymbol*>*)_getSymbolsByNames:(NSArray<NSString*>*)names fromCollection:(IDEIndexCollection*)collection;
127-
128127
/// Returns a boolean value whether `symbolKind` means a enum type.
129128
- (BOOL)isSymbolKindEnum:(DVTSourceCodeSymbolKind *)symbol;
130129

@@ -167,63 +166,46 @@ - (DVTSourceCodeLanguageKind)currentLanguage
167166

168167
@implementation DVTTextCompletionListWindowController (SCXcodeSwitchExpander)
169168

170-
- (NSArray<IDEIndexSymbol*>*)_getSymbolsByName:(NSString*)name fromCollection:(IDEIndexCollection*)collection
171-
{
172-
NSMutableArray<IDEIndexSymbol*> *results = [[NSMutableArray alloc] init];
173-
174-
for (IDEIndexSymbol *symbol in collection)
175-
{
176-
if ([symbol.name isEqualToString:name])
177-
{
178-
[results addObject:symbol];
179-
}
180-
}
181-
182-
return [results copy];
183-
}
184169

185-
- (NSArray<IDEIndexSymbol*>*)_getSymbolsByNames:(NSArray<NSString*>*)names fromCollection:(IDEIndexCollection*)collection
170+
- (NSArray<IDEIndexSymbol*>*)getSymbolsByFullName:(NSString*)fullSymbolName forLanguage:(DVTSourceCodeLanguageKind)language fromIndex:(IDEIndex*)index
186171
{
187-
NSString* name = names.firstObject;
188-
NSArray<NSString*> *subNames = [names subarrayWithRange:NSMakeRange(1, names.count - 1)];
172+
NSArray<NSString*> *names = symbolNamesFromFullSymbolName(fullSymbolName, language);
173+
NSString *lastName = names.lastObject;
189174

190-
for (IDEIndexSymbol *symbol in collection)
175+
NSArray<IDEIndexSymbol*> *symbols = [[index allSymbolsMatchingName:lastName kind:nil] allObjects];
176+
NSIndexSet *enumSymbolIndexes = [symbols indexesOfObjectsPassingTest:^BOOL(IDEIndexSymbol * _Nonnull symbol, NSUInteger idx, BOOL * _Nonnull stop) {
177+
return [self isSymbolKindEnum:symbol.symbolKind];
178+
}];
179+
NSArray<IDEIndexSymbol*> *enumSymbols = [symbols objectsAtIndexes:enumSymbolIndexes];
180+
181+
for (NSInteger nameIndex = names.count - 2; nameIndex != -1; ++nameIndex)
191182
{
192-
if ([symbol.name isEqualToString:name] && [symbol isKindOfClass:[IDEIndexContainerSymbol class]])
183+
if (enumSymbols.count <= 1)
193184
{
194-
NSArray<IDEIndexSymbol*>* symbols = [self findSymbolsWithNames:subNames fromCollection:[(IDEIndexContainerSymbol*)symbol children]];
185+
break;
186+
}
187+
188+
NSString *currentName = [names objectAtIndex:nameIndex];
189+
NSArray<IDEIndexSymbol*> *currentSymbols = [[index allSymbolsMatchingName:currentName kind:nil] allObjects];
195190

196-
if (symbols.count > 0)
191+
NSIndexSet *validEnumSymbolIndexes = [enumSymbols indexesOfObjectsPassingTest:^BOOL(IDEIndexSymbol * _Nonnull enumSymbol, NSUInteger idx, BOOL * _Nonnull stop) {
192+
NSString *enumSymbolNamespace = namespaceFromResolutionOfSymbol(enumSymbol);
193+
for (IDEIndexSymbol *currentSymbol in currentSymbols)
197194
{
198-
return symbols;
195+
NSString *currentSymbolNamespace = namespaceFromResolutionOfSymbol(currentSymbol);
196+
if ([enumSymbolNamespace hasPrefix:currentSymbolNamespace])
197+
{
198+
return true;
199+
}
199200
}
200-
}
201+
return false;
202+
}];
203+
204+
enumSymbols = [enumSymbols objectsAtIndexes:validEnumSymbolIndexes];
201205
}
202206

203-
return nil;
204-
}
205-
206-
- (NSArray<IDEIndexSymbol*>*)findSymbolsWithNames:(NSArray<NSString*>*)names fromCollection:(IDEIndexCollection*)collection
207-
{
208-
switch (names.count)
209-
{
210-
case 0:
211-
return @[];
212-
213-
case 1:
214-
return [self _getSymbolsByName:names.firstObject fromCollection:collection];
215-
216-
default:
217-
return [self _getSymbolsByNames:names fromCollection:collection];
218-
}
219-
}
220-
221-
- (NSArray<IDEIndexSymbol*>*)getSymbolsByFullName:(NSString*)fullSymbolName forLanguage:(DVTSourceCodeLanguageKind)language fromIndex:(IDEIndex*)index
222-
{
223-
NSArray<NSString*> *names = symbolNamesFromFullSymbolName(fullSymbolName, language);
224-
IDEIndexCollection *collection = [index allSymbolsMatchingName:names.firstObject kind:nil];
225-
226-
return [self findSymbolsWithNames:names fromCollection:collection];
207+
// return [self findSymbolsWithNames:names fromCollection:collection];
208+
return enumSymbols;
227209
}
228210

229211
- (BOOL)tryExpandingSwitchStatementForLanguage:(DVTSourceCodeLanguageKind)language
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// IDEIndexClassSymbol.h
3+
// SCXcodeSwitchExpander
4+
//
5+
// Created by Tomohiro Kumagai on 4/11/16.
6+
// Copyright © 2016 Stefan Ceriu. All rights reserved.
7+
//
8+
9+
#import "IDEIndexContainerSymbol.h"
10+
11+
@interface IDEIndexClassSymbol : IDEIndexContainerSymbol
12+
13+
@end
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// IDEIndexClassSymbol.m
3+
// SCXcodeSwitchExpander
4+
//
5+
// Created by Tomohiro Kumagai on 4/11/16.
6+
// Copyright © 2016 Stefan Ceriu. All rights reserved.
7+
//
8+
9+
#import "IDEIndexClassSymbol.h"
10+
11+
@implementation IDEIndexClassSymbol
12+
13+
@end

SCXcodeSwitchExpander/Xcode Headers/IDEIndexSymbol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
@interface IDEIndexSymbol : NSObject
1212

13+
@property(readonly, nonatomic) NSString *resolution;
1314
@property(readonly, nonatomic) NSString *name;
1415
@property(readonly, nonatomic) DVTSourceCodeSymbolKind *symbolKind;
1516

0 commit comments

Comments
 (0)