Переглянути джерело

Fix runtime browser crashing when searching for *.*.

Also add type annotations to several arrays
Tanner Bennett 6 роки тому
батько
коміт
c037e703a6

+ 3 - 3
Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.h

@@ -20,7 +20,7 @@
 - (void)reloadLibrariesList;
 - (void)reloadLibrariesList;
 
 
 /// An array of strings representing the currently loaded libraries.
 /// An array of strings representing the currently loaded libraries.
-@property (nonatomic, readonly) NSArray<NSString*> *imageDisplayNames;
+@property (nonatomic, readonly) NSArray<NSString *> *imageDisplayNames;
 
 
 /// "Image name" is the path of the bundle
 /// "Image name" is the path of the bundle
 - (NSString *)shortNameForImageName:(NSString *)imageName;
 - (NSString *)shortNameForImageName:(NSString *)imageName;
@@ -37,7 +37,7 @@
 /// @return A list of lists of \c FLEXMethods where
 /// @return A list of lists of \c FLEXMethods where
 /// each list corresponds to one of the given classes
 /// each list corresponds to one of the given classes
 - (NSArray<NSMutableArray<FLEXMethod *> *> *)methodsForToken:(FLEXSearchToken *)token
 - (NSArray<NSMutableArray<FLEXMethod *> *> *)methodsForToken:(FLEXSearchToken *)token
-                                      instance:(NSNumber *)onlyInstanceMethods
-                                     inClasses:(NSArray<NSString*> *)classes;
+                                                    instance:(NSNumber *)onlyInstanceMethods
+                                                   inClasses:(NSArray<NSString *> *)classes;
 
 
 @end
 @end

+ 12 - 12
Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.m

@@ -19,13 +19,13 @@
 
 
 
 
 @interface FLEXRuntimeClient () {
 @interface FLEXRuntimeClient () {
-    NSMutableArray<NSString*> *_imageDisplayNames;
+    NSMutableArray<NSString *> *_imageDisplayNames;
 }
 }
 
 
 @property (nonatomic) NSMutableDictionary *bundles_pathToShort;
 @property (nonatomic) NSMutableDictionary *bundles_pathToShort;
 @property (nonatomic) NSMutableDictionary *bundles_shortToPath;
 @property (nonatomic) NSMutableDictionary *bundles_shortToPath;
 @property (nonatomic) NSCache *bundles_pathToClassNames;
 @property (nonatomic) NSCache *bundles_pathToClassNames;
-@property (nonatomic) NSMutableArray<NSString*> *imagePaths;
+@property (nonatomic) NSMutableArray<NSString *> *imagePaths;
 
 
 @end
 @end
 
 
@@ -159,7 +159,7 @@ static inline NSString * TBWildcardMap(NSString *token, NSString *candidate, TBW
     return _bundles_shortToPath[imageName];
     return _bundles_shortToPath[imageName];
 }
 }
 
 
-- (NSMutableArray<NSString*> *)classNamesInImageAtPath:(NSString *)path {
+- (NSMutableArray<NSString *> *)classNamesInImageAtPath:(NSString *)path {
     // Check cache
     // Check cache
     NSMutableArray *classNameStrings = [_bundles_pathToClassNames objectForKey:path];
     NSMutableArray *classNameStrings = [_bundles_pathToClassNames objectForKey:path];
     if (classNameStrings) {
     if (classNameStrings) {
@@ -187,7 +187,7 @@ static inline NSString * TBWildcardMap(NSString *token, NSString *candidate, TBW
 
 
 #pragma mark - Public
 #pragma mark - Public
 
 
-- (NSMutableArray<NSString*> *)bundleNamesForToken:(FLEXSearchToken *)token {
+- (NSMutableArray<NSString *> *)bundleNamesForToken:(FLEXSearchToken *)token {
     if (self.imagePaths.count) {
     if (self.imagePaths.count) {
         TBWildcardOptions options = token.options;
         TBWildcardOptions options = token.options;
         NSString *query = token.string;
         NSString *query = token.string;
@@ -207,7 +207,7 @@ static inline NSString * TBWildcardMap(NSString *token, NSString *candidate, TBW
     return [NSMutableArray new];
     return [NSMutableArray new];
 }
 }
 
 
-- (NSMutableArray<NSString*> *)bundlePathsForToken:(FLEXSearchToken *)token {
+- (NSMutableArray<NSString *> *)bundlePathsForToken:(FLEXSearchToken *)token {
     if (self.imagePaths.count) {
     if (self.imagePaths.count) {
         TBWildcardOptions options = token.options;
         TBWildcardOptions options = token.options;
         NSString *query = token.string;
         NSString *query = token.string;
@@ -227,7 +227,7 @@ static inline NSString * TBWildcardMap(NSString *token, NSString *candidate, TBW
     return [NSMutableArray new];
     return [NSMutableArray new];
 }
 }
 
 
-- (NSMutableArray<NSString*> *)classesForToken:(FLEXSearchToken *)token inBundles:(NSMutableArray<NSString*> *)bundles {
+- (NSMutableArray<NSString *> *)classesForToken:(FLEXSearchToken *)token inBundles:(NSMutableArray<NSString *> *)bundles {
     // Edge case where token is the class we want already; return superclasses
     // Edge case where token is the class we want already; return superclasses
     if (token.isAbsolute) {
     if (token.isAbsolute) {
         if (FLEXClassIsSafe(NSClassFromString(token.string))) {
         if (FLEXClassIsSafe(NSClassFromString(token.string))) {
@@ -239,18 +239,18 @@ static inline NSString * TBWildcardMap(NSString *token, NSString *candidate, TBW
 
 
     if (bundles.count) {
     if (bundles.count) {
         // Get class names, remove unsafe classes
         // Get class names, remove unsafe classes
-        NSMutableArray<NSString*> *names = [self _classesForToken:token inBundles:bundles];
-        return [names flex_mapped:^NSString *(NSString *cls, NSUInteger idx) {
-            NSSet *ignored = FLEXKnownUnsafeClassNames();
-            BOOL safe = ![ignored containsObject:cls];
-            return safe ? cls : nil;
+        NSMutableArray<NSString *> *names = [self _classesForToken:token inBundles:bundles];
+        return [names flex_mapped:^NSString *(NSString *name, NSUInteger idx) {
+            Class cls = NSClassFromString(name);
+            BOOL safe = FLEXClassIsSafe(cls);
+            return safe ? name : nil;
         }];
         }];
     }
     }
 
 
     return [NSMutableArray new];
     return [NSMutableArray new];
 }
 }
 
 
-- (NSMutableArray<NSString*> *)_classesForToken:(FLEXSearchToken *)token inBundles:(NSMutableArray<NSString*> *)bundles {
+- (NSMutableArray<NSString *> *)_classesForToken:(FLEXSearchToken *)token inBundles:(NSMutableArray<NSString *> *)bundles {
     TBWildcardOptions options = token.options;
     TBWildcardOptions options = token.options;
     NSString *query = token.string;
     NSString *query = token.string;
 
 

+ 5 - 3
Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeController.m

@@ -142,14 +142,16 @@ static FLEXRuntimeController *controller = nil;
 
 
     if (shouldCache) {
     if (shouldCache) {
         key = [@[bundleToken.description, classToken.description] componentsJoinedByString:@"+"];
         key = [@[bundleToken.description, classToken.description] componentsJoinedByString:@"+"];
-        NSMutableArray<NSString*> *cached = [self.classNamesCache objectForKey:key];
+        NSMutableArray<NSString *> *cached = [self.classNamesCache objectForKey:key];
         if (cached) {
         if (cached) {
             return cached;
             return cached;
         }
         }
     }
     }
 
 
-    NSMutableArray *bundles = [self bundlePathsForToken:bundleToken];
-    NSMutableArray *classes = [FLEXRuntimeClient.runtime classesForToken:classToken inBundles:bundles];
+    NSMutableArray<NSString *> *bundles = [self bundlePathsForToken:bundleToken];
+    NSMutableArray<NSString *> *classes = [FLEXRuntimeClient.runtime
+        classesForToken:classToken inBundles:bundles
+    ];
 
 
     if (shouldCache) {
     if (shouldCache) {
         [self.classNamesCache setObject:classes forKey:key];
         [self.classNamesCache setObject:classes forKey:key];

+ 10 - 5
Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyPathSearchController.m

@@ -176,8 +176,10 @@
             ].mutableCopy;
             ].mutableCopy;
             
             
             // Remove classes without results if we're searching for a method
             // Remove classes without results if we're searching for a method
-            FLEXSearchToken *methodKey = self.keyPath.methodKey;
-            if (methodKey && !methodKey.isAny) {
+            //
+            // Note: this will remove classes without any methods or overrides
+            // even if the query doesn't specify a method, like `*.*.`
+            if (self.keyPath.methodKey) {
                 [self setNonEmptyMethodLists:methods withClasses:self.classes.mutableCopy];
                 [self setNonEmptyMethodLists:methods withClasses:self.classes.mutableCopy];
             } else {
             } else {
                 self.filteredClasses = self.classes;
                 self.filteredClasses = self.classes;
@@ -190,8 +192,10 @@
                 self.bundlesOrClasses = nil;
                 self.bundlesOrClasses = nil;
                 
                 
                 NSMutableArray *methods = models.mutableCopy;
                 NSMutableArray *methods = models.mutableCopy;
-                NSMutableArray *classes = [FLEXRuntimeController classesForKeyPath:keyPath];
-                self.classes = classes.copy;
+                NSMutableArray<NSString *> *classes = [
+                    FLEXRuntimeController classesForKeyPath:keyPath
+                ];
+                self.classes = classes;
                 [self setNonEmptyMethodLists:methods withClasses:classes];
                 [self setNonEmptyMethodLists:methods withClasses:classes];
             } else { // We're looking at bundles or classes
             } else { // We're looking at bundles or classes
                 self.bundlesOrClasses = models;
                 self.bundlesOrClasses = models;
@@ -213,7 +217,8 @@
 }
 }
 
 
 /// Assign assign .filteredClasses and .classesToMethods after removing empty sections
 /// Assign assign .filteredClasses and .classesToMethods after removing empty sections
-- (void)setNonEmptyMethodLists:(NSMutableArray<NSArray *> *)methods withClasses:(NSMutableArray *)classes {
+- (void)setNonEmptyMethodLists:(NSMutableArray<NSArray<FLEXMethod *> *> *)methods
+                   withClasses:(NSMutableArray<NSString *> *)classes {
     // Remove sections with no methods
     // Remove sections with no methods
     NSIndexSet *allEmpty = [methods indexesOfObjectsPassingTest:^BOOL(NSArray *list, NSUInteger idx, BOOL *stop) {
     NSIndexSet *allEmpty = [methods indexesOfObjectsPassingTest:^BOOL(NSArray *list, NSUInteger idx, BOOL *stop) {
         return list.count == 0;
         return list.count == 0;