Skip to content

Commit e0e70f6

Browse files
authored
Add Obj-C AST support (#40)
1 parent 81c805d commit e0e70f6

File tree

6 files changed

+912
-17
lines changed

6 files changed

+912
-17
lines changed

lib/reaper/ast_parser.rb

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,22 @@ class AstParser
99
DECLARATION_NODE_TYPES = {
1010
'swift' => %i[class_declaration protocol_declaration],
1111
'kotlin' => %i[class_declaration protocol_declaration interface_declaration object_declaration],
12-
'java' => %i[class_declaration protocol_declaration interface_declaration]
12+
'java' => %i[class_declaration protocol_declaration interface_declaration],
13+
'objc' => %i[class_declaration protocol_declaration class_implementation class_interface]
1314
}.freeze
1415

1516
IDENTIFIER_NODE_TYPES = {
1617
'swift' => %i[simple_identifier qualified_name identifier type_identifier],
1718
'kotlin' => %i[simple_identifier qualified_name identifier type_identifier],
18-
'java' => %i[simple_identifier qualified_name identifier type_identifier]
19+
'java' => %i[simple_identifier qualified_name identifier type_identifier],
20+
'objc' => %i[simple_identifier qualified_name identifier type_identifier]
1921
}.freeze
2022

2123
COMMENT_AND_IMPORT_NODE_TYPES = {
2224
'swift' => %i[comment import_declaration],
2325
'kotlin' => %i[comment import_header],
24-
'java' => %i[comment import_declaration]
26+
'java' => %i[comment import_declaration],
27+
'objc' => %i[comment import_declaration preproc_include]
2528
}.freeze
2629

2730
attr_reader :parser, :language
@@ -52,17 +55,9 @@ def initialize(language)
5255
extension = platform == 'darwin' ? 'dylib' : 'so'
5356
parser_file = "libtree-sitter-#{language}-#{platform}-#{arch}.#{extension}"
5457
parser_path = File.join('parsers', parser_file)
58+
raise "No language grammar found for #{language}" unless File.exist?(parser_path)
5559

56-
case language
57-
when 'swift'
58-
@parser.language = TreeSitter::Language.load('swift', parser_path)
59-
when 'kotlin'
60-
@parser.language = TreeSitter::Language.load('kotlin', parser_path)
61-
when 'java'
62-
@parser.language = TreeSitter::Language.load('java', parser_path)
63-
else
64-
raise "Unsupported language: #{language}"
65-
end
60+
@parser.language = TreeSitter::Language.load(language, parser_path)
6661
end
6762

6863
# Deletes a type from the given file contents.
@@ -127,6 +122,7 @@ def find_usages(file_contents:, type_name:)
127122

128123
while (node = nodes_to_process.shift)
129124
identifier_type = identifier_node_types.include?(node.type)
125+
Logger.debug "Processing node: #{node.type} #{node_text(node)}"
130126
declaration_type = if node == tree.root_node
131127
false
132128
else
@@ -136,6 +132,11 @@ def find_usages(file_contents:, type_name:)
136132
usages << { line: node.start_point.row, usage_type: 'declaration' }
137133
elsif identifier_type && node_text(node) == type_name
138134
usages << { line: node.start_point.row, usage_type: 'identifier' }
135+
elsif node.type == :@implementation
136+
next_sibling = node.next_named_sibling
137+
if next_sibling.type == :identifier && node_text(next_sibling) == type_name
138+
usages << { line: next_sibling.start_point.row, usage_type: 'declaration' }
139+
end
139140
end
140141

141142
node.each { |child| nodes_to_process.push(child) }
@@ -172,14 +173,14 @@ def delete_usage(file_contents:, type_name:)
172173

173174
return file_contents if nodes_to_remove.empty?
174175

175-
Logger.debug "Found #{nodes_to_remove.length} nodes to remove"
176+
Logger.debug "Found #{nodes_to_remove.length} nodes to remove"
176177
remove_nodes_from_content(file_contents, nodes_to_remove)
177178
end
178179

179180
private
180181

181182
def remove_node(node, lines_to_remove)
182-
Logger.debug "Removing node: #{node.type}"
183+
Logger.debug "Removing node: #{node.type}"
183184
start_position = node.start_point.row
184185
end_position = node.end_point.row
185186
lines_to_remove << { start: start_position, end: end_position }
@@ -287,7 +288,7 @@ def find_removable_parent(node)
287288
when :navigation_expression # NetworkDebugger.printStats
288289
result = handle_navigation_expression(current)
289290
return result if result
290-
when :class_declaration, :function_declaration, :method_declaration
291+
when :class_declaration, :function_declaration, :method_declaration, :@implementation
291292
Logger.debug "Reached structural element, stopping at: #{current.type}"
292293
break
293294
end

lib/reaper/code_deleter.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ def find_type_in_project(type_name)
163163
found_usages = []
164164
source_patterns = case @platform&.downcase
165165
when 'ios'
166-
{ 'swift' => '**/*.swift' }
166+
{ 'swift' => '**/*.swift',
167+
'objc' => '**/*.{m,h}' }
167168
when 'android'
168169
{
169170
'kotlin' => '**/*.kt',
@@ -253,6 +254,7 @@ def make_parser_for_file(file_path)
253254
when '.swift' then 'swift'
254255
when '.kt' then 'kotlin'
255256
when '.java' then 'java'
257+
when '.m', '.h' then 'objc'
256258
else
257259
raise "Unsupported file type for #{file_path}"
258260
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// EMGURLProtocol.h
3+
// PerfTesting
4+
//
5+
// Created by Noah Martin on 8/4/22.
6+
//
7+
8+
#import "EMGTuple.h"
9+
#import <Foundation/Foundation.h>
10+
11+
NS_ASSUME_NONNULL_BEGIN
12+
13+
@interface EMGURLProtocol : NSURLProtocol
14+
15+
+ (NSError *)responseNotFoundErrorWithType:(NSString *)type
16+
cachedValue:(NSString *)cachedValue
17+
givenValue:(NSString *)givenValue;
18+
19+
+ (NSArray<NSDictionary *> *)requestMisses;
20+
21+
+ (NSString *)folderNameForURL:(NSURL *)url;
22+
23+
+ (BOOL)isCachedRequestEqual:(NSURLRequest *)req1
24+
to:(NSURLRequest *)req2
25+
error:(NSError **)error;
26+
27+
@end
28+
29+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)