git.fiddlerwoaroof.com
Browse code

feat: replace lisp regex with tree sitter for java

Ed Langley authored on 04/02/2020 19:38:17
Showing 8 changed files
... ...
@@ -1,6 +1,6 @@
1 1
 /* Localized versions of Info.plist keys */
2 2
 
3
-CFBundleName = "Lisp Metadata Importer";
4
-CFBundleShortVersionString = "0.0.2";
5
-CFBundleGetInfoString = "Lisp Metadata Importer version 0.0.1, Copyright (c) 2005 John Wiseman (jjwiseman@yahoo.com)";
6
-NSHumanReadableCopyright = "Copyright (c) 2005 John Wiseman (jjwiseman@yahoo.com)";
3
+CFBundleName = "tree-sitter-metadata-importer";
4
+CFBundleShortVersionString = "0.0.3";
5
+CFBundleGetInfoString = "Tree Sitter Metadata Importer version 0.0.1, Copyright (c) 2020 Ed L";
6
+NSHumanReadableCopyright = "Copyright (c) 2020 Ed L";
... ...
@@ -1,17 +1,11 @@
1
-"org_lisp_definitions" = "Lisp Definitions";
2
-"org_lisp_defuns" = "Lisp Defuns";
3
-"org_lisp_defmethods" = "Lisp Defmethods";
4
-"org_lisp_defgenerics" = "Lisp Defgenerics";
5
-"org_lisp_defmacros" = "Lisp Defmacros";
6
-"org_lisp_defvars" = "Lisp Defvars";
7
-"org_lisp_defclasses" = "Lisp Defclasses";
8
-"org_lisp_defstructs" = "Lisp Defstructs";
1
+"co_fwoar_java_classes" = "Java Classes";
2
+"co_fwoar_java_methods" = "Java Methods";
3
+"co_fwoar_java_interfaces" = "Java Interfaces";
4
+"co_fwoar_java_definitions" = "Java Definitions";
5
+"co_fwoar_java_package" = "Java Package";
9 6
 
10
-"org_lisp_definitions.Description" = "Functions, classes structs and other objects defined in a Lisp file";
11
-"org_lisp_defuns.Description" = "Functions defined in a Lisp file";
12
-"org_lisp_defmethods.Description" = "Methods defined in a Lisp file";
13
-"org_lisp_defgenerics.Description" = "Generic functions defined in a Lisp file";
14
-"org_lisp_defmacros.Description" = "Macros defined in a Lisp file";
15
-"org_lisp_defvars.Description" = "Variables, parameters and constants defined in a Lisp file";
16
-"org_lisp_defclasses.Description" = "Classes defined in a Lisp file";
17
-"org_lisp_defstructs.Description" = "Structures defined in a Lisp file";
7
+"co_fwoar_java_methods.Description" = "Methods in a Java file";
8
+"co_fwoar_java_interfaces.Description" = "Interfaces in a Java file";
9
+"co_fwoar_java_definitions.Description" = "Definitions in a Java file";
10
+"co_fwoar_java_classes.Description" = "Classes in a Java file";
11
+"co_fwoar_java_package.Description" = "Package for a Java file";
... ...
@@ -11,20 +11,22 @@
11 11
 			<string>MDImporter</string>
12 12
 			<key>LSItemContentTypes</key>
13 13
 			<array>
14
-				<string>org.lisp.lisp-source</string>
14
+				<string>com.sun.java-source</string>
15 15
 			</array>
16 16
 		</dict>
17 17
 	</array>
18 18
 	<key>CFBundleExecutable</key>
19
-	<string>Lisp Metadata Importer</string>
19
+	<string>tree-sitter-metadata-importer</string>
20 20
 	<key>CFBundleIconFile</key>
21 21
 	<string></string>
22 22
 	<key>CFBundleIdentifier</key>
23 23
 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
24 24
 	<key>CFBundleInfoDictionaryVersion</key>
25 25
 	<string>6.0</string>
26
-	<key>CFBundleVersion</key>
26
+	<key>CFBundleShortVersionString</key>
27 27
 	<string>0.0.2</string>
28
+	<key>CFBundleVersion</key>
29
+	<string>1</string>
28 30
 	<key>CFPlugInDynamicRegisterFunction</key>
29 31
 	<string></string>
30 32
 	<key>CFPlugInDynamicRegistration</key>
... ...
@@ -5,21 +5,17 @@
5 5
     xsi:schemaLocation="http://www.apple.com/metadata file:///System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/MetadataSchema.xsd">
6 6
     
7 7
     <attributes>
8
-        <attribute name="org_lisp_definitions" multivalued="true" type="CFString"/>
9
-        <attribute name="org_lisp_defuns" multivalued="true" type="CFString"/>
10
-        <attribute name="org_lisp_defmethods" multivalued="true" type="CFString"/>
11
-        <attribute name="org_lisp_defpackages" multivalued="true" type="CFString"/>
12
-        <attribute name="org_lisp_defgenerics" multivalued="true" type="CFString"/>
13
-        <attribute name="org_lisp_defmacros" multivalued="true" type="CFString"/>
14
-        <attribute name="org_lisp_defvars" multivalued="true" type="CFString"/>
15
-        <attribute name="org_lisp_defclasses" multivalued="true" type="CFString"/>
16
-        <attribute name="org_lisp_defstructs" multivalued="true" type="CFString"/>
8
+        <attribute name="co_fwoar_java_package" multivalued="false" type="CFString"/>
9
+        <attribute name="co_fwoar_java_classes" multivalued="true" type="CFString"/>
10
+        <attribute name="co_fwoar_java_interfaces" multivalued="true" type="CFString"/>
11
+        <attribute name="co_fwoar_java_methods" multivalued="true" type="CFString"/>
12
+        <attribute name="co_fwoar_java_definitions" multivalued="true" type="CFString"/>
17 13
     </attributes>
18 14
     
19 15
     <types>
20
-        <type name="org.lisp.lisp-source">
21
-            <allattrs>kMDItemTextContent org_lisp_definitions org_lisp_defuns org_lisp_defmethods org_lisp_defgenerics org_lisp_defmacros org_lisp_defvars org_lisp_defclasses org_lisp_defstructs</allattrs>
22
-            <displayattrs>org_lisp_defpackages org_lisp_defclasses org_lisp_defgenerics org_lisp_defuns org_lisp_defmacros</displayattrs>
16
+        <type name="com.sun.java-source">
17
+            <allattrs>kMDItemTextContent co_fwoar_java_package co_fwoar_java_classes co_fwoar_java_interfaces co_fwoar_java_methods co_fwoar_java_definitions</allattrs>
18
+            <displayattrs>co_fwoar_java_package co_fwoar_java_classes co_fwoar_java_interfaces</displayattrs>
23 19
         </type>
24 20
     </types>
25 21
 </schema>
... ...
@@ -22,7 +22,7 @@
22 22
 // "Private" methods.
23 23
 
24 24
 - (void)initStaticData;
25
-- (BOOL)addMatchesTo:(NSMutableDictionary *)attributes fromLine:(NSString *)line usingRE:(NSRegularExpression *)regex forKey:(NSString *)key;
25
+- (BOOL)addMatchesTo:(NSMutableDictionary *)attributes fromCString:(const char *)inp forKey:(NSString *)key;
26 26
 - (NSString*)readContentsOfFile:(NSString*)path error:(NSError**)theError;
27 27
 
28 28
 @end
... ...
@@ -13,6 +13,9 @@
13 13
 #import "NSString_HMext.h"
14 14
 #import "NSData_HMext.h"
15 15
 #import "DebugLog.h"
16
+#include "tree_sitter/api.h"
17
+#include "tree-sitter/lib/src/lib.c"
18
+#include "tree-sitter-java/src/parser.c"
16 19
 
17 20
 @implementation CMetadataImporter
18 21
 
... ...
@@ -24,57 +27,51 @@ long NO_MAXIMUM = -1;
24 27
 // All sorts of static data that we initialize once, then use many many times.
25 28
 
26 29
 static BOOL StaticDataIsInitialized = NO;
30
+static const TSLanguage* ts_language_java;
31
+char* package_query_str = "(package_declaration (scoped_identifier) @package)";
32
+TSQuery *package_query;
27 33
 
28
-// Lots of regexes in string form, waiting to be compiled.
34
+char* class_query_str = "(class_declaration name: (identifier) @class)";
35
+TSQuery* class_query;
29 36
 
30
-static NSString *LispDef1_pat = @"(?i)^\\(def[^\\s]*[\\s\\']+(\\(setf\\s+[^\\s]+\\))";
31
-static NSRegularExpression *LispDef1_RE = nil;
37
+char* interface_query_str = "(interface_declaration name: (identifier) @interface)";
38
+TSQuery* interface_query;
32 39
 
33
-static NSString *LispDef2_pat = @"(?i)^\\(def[^\\s]*[\\s\\']+([^\\s\\)]+)";
34
-static NSRegularExpression *LispDef2_RE = nil;
35
-
36
-static NSString *LispDefun_pat = @"(?i)^\\(defun\\s+([^\\s\\)\\(]+)";
37
-static NSRegularExpression *LispDefun_RE = nil;
38
-
39
-static NSString *LispDefunsetf_pat = @"(?i)^\\(defun\\s+(\\(setf\\s+[^\\s]+\\))";
40
-static NSRegularExpression *LispDefunsetf_RE = nil;
41
-
42
-static NSString *LispDefmethod_pat = @"(?i)^\\(defmethod\\s+([^\\s\\)\\(]+)";
43
-static NSRegularExpression *LispDefmethod_RE = nil;
44
-
45
-static NSString *LispDefmethodsetf_pat = @"(?i)^\\(defmethod\\s+(\\(setf\\s+[^\\s]+\\))";
46
-static NSRegularExpression *LispDefmethodsetf_RE = nil;
47
-
48
-static NSString *LispDefgeneric_pat = @"(?i)^\\(defgeneric\\s+((?:[^\\s\\)\\(]+|\\(setf\\s+[^\\s]+\\)))";
49
-static NSRegularExpression *LispDefgeneric_RE = nil;
50
-
51
-static NSString *LispDefgenericsetf_pat = @"(?i)^\\(defgeneric\\s+(\\(setf\\s+[^\\s]+\\))";
52
-static NSRegularExpression *LispDefgenericsetf_RE = nil;
53
-
54
-static NSString *LispDefmacro_pat = @"(?i)^\\(defmacro\\s+([^\\s\\)]+)";
55
-static NSRegularExpression *LispDefmacro_RE = nil;
56
-
57
-static NSString *LispDefclass_pat = @"(?i)^\\(defclass\\s+([^\\s\\)]+)";
58
-static NSRegularExpression *LispDefclass_RE = nil;
59
-
60
-static NSString *LispDefstruct_pat = @"(?i)^\\(defstruct\\s+\\(?([^\\s\\)]+)";
61
-static NSRegularExpression *LispDefstruct_RE = nil;
62
-
63
-static NSString *LispDefvar_pat = @"(?i)^\\((?:defvar|defparameter|defconstant)\\s+([^\\s\\)]+)";
64
-static NSRegularExpression *LispDefvar_RE = nil;
65
-
66
-static NSError *err = nil;
40
+char* method_query_str = "(class_declaration name: (identifier) @class body: (class_body (method_declaration name: (identifier) @method (formal_parameters) @type)))(interface_declaration name: (identifier) @interface body: (interface_body (method_declaration name: (identifier) @method (formal_parameters) @type)))";
41
+TSQuery* method_query;
42
+//static TSQuery method_query;
43
+//static TSQuery field_query;
44
+//
45
+//static NSError *err = nil;
67 46
 
68 47
 - (void)initStaticData
69 48
 {
70
-    NSLog(@"Import Lisp");
71 49
     if (StaticDataIsInitialized)
72 50
     {
73 51
         return;
74 52
     }
75
-    
76 53
     StaticDataIsInitialized = YES;
77 54
     
55
+    uint32_t error_offset;
56
+    TSQueryError error_type;
57
+    
58
+    method_query = ts_query_new(ts_language_java, method_query_str, (uint32_t)strlen(method_query_str), &error_offset, &error_type);
59
+    if (error_type != 0) {
60
+        NSLog(@"error while initializing method query offset: %d, type: %d", error_offset, error_type);
61
+    }
62
+    interface_query = ts_query_new(ts_language_java, interface_query_str, (uint32_t)strlen(interface_query_str), &error_offset, &error_type);
63
+    if (error_type != 0) {
64
+        NSLog(@"error while initializing interface query offset: %d, type: %d", error_offset, error_type);
65
+    }
66
+    class_query = ts_query_new(ts_language_java, class_query_str, (uint32_t)strlen(class_query_str), &error_offset, &error_type);
67
+    if (error_type != 0) {
68
+        NSLog(@"error while initializing class query offset: %d, type: %d", error_offset, error_type);
69
+    }
70
+    package_query = ts_query_new(ts_language_java, package_query_str, (uint32_t)strlen(package_query_str), &error_offset, &error_type);
71
+    if (error_type != 0) {
72
+        NSLog(@"error while initializing package query offset: %d type: %d", error_offset, error_type);
73
+    }
74
+
78 75
     // Find the bundle, and Info.plist.  Set the debug level specified
79 76
     // there, as well as the maximum file length to index.
80 77
     NSBundle *theBundle = [NSBundle bundleForClass:[self class]];
... ...
@@ -98,42 +95,6 @@ static NSError *err = nil;
98 95
     }
99 96
     
100 97
     // Precompile our regexes.
101
-    LispDef1_RE = [NSRegularExpression regularExpressionWithPattern:LispDef1_pat
102
-                                                            options:NSRegularExpressionCaseInsensitive
103
-                                                              error:&err];
104
-    LispDef2_RE = [NSRegularExpression regularExpressionWithPattern:LispDef2_pat
105
-                                                            options:NSRegularExpressionCaseInsensitive
106
-                                                              error:&err];
107
-    LispDefun_RE = [NSRegularExpression regularExpressionWithPattern:LispDefun_pat
108
-                                                             options:NSRegularExpressionCaseInsensitive
109
-                                                               error:&err];
110
-    LispDefunsetf_RE = [NSRegularExpression regularExpressionWithPattern:LispDefunsetf_pat
111
-                                                                 options:NSRegularExpressionCaseInsensitive
112
-                                                                   error:&err];
113
-    LispDefmethod_RE = [NSRegularExpression regularExpressionWithPattern:LispDefmethod_pat
114
-                                                                 options:NSRegularExpressionCaseInsensitive
115
-                                                                   error:&err];
116
-    LispDefmethodsetf_RE = [NSRegularExpression regularExpressionWithPattern:LispDefmethodsetf_pat
117
-                                                                     options:NSRegularExpressionCaseInsensitive
118
-                                                                       error:&err];
119
-    LispDefgeneric_RE = [NSRegularExpression regularExpressionWithPattern:LispDefgeneric_pat
120
-                                                                  options:NSRegularExpressionCaseInsensitive
121
-                                                                    error:&err];
122
-    LispDefgenericsetf_RE = [NSRegularExpression regularExpressionWithPattern:LispDefgenericsetf_pat
123
-                                                                      options:NSRegularExpressionCaseInsensitive
124
-                                                                        error:&err];
125
-    LispDefclass_RE = [NSRegularExpression regularExpressionWithPattern:LispDefclass_pat
126
-                                                                options:NSRegularExpressionCaseInsensitive
127
-                                                                  error:&err];
128
-    LispDefstruct_RE = [NSRegularExpression regularExpressionWithPattern:LispDefstruct_pat
129
-                                                                 options:NSRegularExpressionCaseInsensitive
130
-                                                                   error:&err];
131
-    LispDefvar_RE = [NSRegularExpression regularExpressionWithPattern:LispDefvar_pat
132
-                                                              options:NSRegularExpressionCaseInsensitive
133
-                                                                error:&err];
134
-    LispDefmacro_RE = [NSRegularExpression regularExpressionWithPattern:LispDefmacro_pat
135
-                                                                options:NSRegularExpressionCaseInsensitive
136
-                                                                  error:&err];
137 98
     
138 99
     DebugLog(DEBUG_LEVEL_DEBUG, @"Static data has been initialized.");
139 100
 }
... ...
@@ -206,28 +167,38 @@ static NSStringEncoding PossibleSourceTextEncodings[] = {	NSUTF8StringEncoding,
206 167
 // Adds metadata values to the specified dictionary under the
207 168
 // specified key, using the specified regular expression.
208 169
 
209
-- (BOOL)addMatchesTo:(NSMutableDictionary *)attributes fromLine:(NSString *)line usingRE:(NSRegularExpression *)regex forKey:(NSString *)key
170
+- (BOOL)addMatchesTo:(NSMutableDictionary *)attributes fromCString:(const char *)inp forKey:(NSString *)key
210 171
 {
211
-    NSTextCheckingResult *match = [regex firstMatchInString:line options:NSMatchingAnchored range:NSMakeRange(0, [line length])];
212
-    if (match)
213
-    {
214
-        NSLog(@"%s", [line UTF8String]);
215
-        NSString *name = [line substringWithRange: [match rangeAtIndex:1]];
216
-        [[attributes objectForKey:key] addObject:name];
217
-        return YES;
218
-    }
219
-    else
220
-    {
221
-        return NO;
172
+    NSString* match = [NSString stringWithUTF8String:inp];
173
+    if (![[attributes objectForKey:key] containsObject:match]) {
174
+        [[attributes objectForKey:key] addObject:match];
222 175
     }
176
+    return YES;
223 177
 }
224 178
 
225 179
 
226 180
 // This is the method that does all the importing and indexing work.
227 181
 // It stuffs attributes into the specified dictionary.
228
-
229 182
 - (BOOL)importFile:(NSString *)inPathToFile contentType:(NSString *)inContentType attributes:(NSMutableDictionary *)inAttributes
230 183
 {
184
+    TSParser* ts_parser;
185
+    
186
+    char *packagename_buf = 0;
187
+    char* classname_buf = 0;
188
+    char* interfacename_buf = 0;
189
+    char* methodname_buf = 0;
190
+
191
+//    char* package_query_str = "(program (package_declaration (scoped_identifier) @package))";
192
+//    TSQuery* package_query;
193
+
194
+    
195
+    ts_parser = ts_parser_new();
196
+    ts_language_java = tree_sitter_java();
197
+    ts_parser_set_language(ts_parser, ts_language_java);
198
+    
199
+    TSQueryCursor *class_cursor = ts_query_cursor_new();
200
+    TSQueryCursor *package_cursor = ts_query_cursor_new();
201
+
231 202
     BOOL theResult = NO;
232 203
     
233 204
     @try
... ...
@@ -250,6 +221,8 @@ static NSStringEncoding PossibleSourceTextEncodings[] = {	NSUTF8StringEncoding,
250 221
                 NSLog(@"Lisp Metadata Importer: Could not process file '%@': unknown error", inPathToFile);
251 222
             }	
252 223
             return NO;
224
+        } else {
225
+            NSLog(@"Processing file '%@'", inPathToFile);
253 226
         }
254 227
         
255 228
         // Only process the first MaxSourceSize of the file.  To try to do more
... ...
@@ -259,46 +232,126 @@ static NSStringEncoding PossibleSourceTextEncodings[] = {	NSUTF8StringEncoding,
259 232
             source = [source substringToIndex:MaxSourceSize];
260 233
         }
261 234
         
262
-        NSMutableDictionary *moreAttributes = [[[NSMutableDictionary alloc] initWithCapacity:10] autorelease];
263
-        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"org_lisp_definitions"];
264
-        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"org_lisp_defuns"];
265
-        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"org_lisp_defmethods"];
266
-        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"org_lisp_defgenerics"];
267
-        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"org_lisp_defmacros"];
268
-        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"org_lisp_defvars"];
269
-        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"org_lisp_defclasses"];
270
-        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"org_lisp_defstructs"];
235
+        const char *cstring_source = [source UTF8String];
236
+        TSTree *tree = ts_parser_parse_string(ts_parser, NULL, cstring_source, strlen(cstring_source));
237
+        TSNode root_node = ts_tree_root_node(tree);
271 238
         
272 239
         
273
-        // Divide the file contents into lines, using either CR or LF to end a line.
274
-        NSCharacterSet *eol = [NSCharacterSet characterSetWithCharactersInString:@"\n\r"];
275
-        NSArray *lines = [source componentsSeparatedByCharacterFromSet:eol];
240
+        NSMutableDictionary *moreAttributes = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease];
276 241
         
277
-        NSEnumerator *theEnum = [lines objectEnumerator];
278
-        NSString *theLine;
242
+        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"co_fwoar_java_package"];
243
+        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"co_fwoar_java_classes"];
244
+        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"co_fwoar_java_interfaces"];
245
+        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"co_fwoar_java_methods"];
246
+        [moreAttributes setObject:[NSMutableArray arrayWithCapacity:100] forKey:@"co_fwoar_java_definitions"];
279 247
         
280
-        while (nil != (theLine = [theEnum nextObject]))
281
-        {
282
-            // The following check speeds the indexer up by roughly 6x.
283
-            if (([theLine length] > 0) && ([theLine characterAtIndex:0] == '('))
284
-            {
285
-                if (![self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDef1_RE forKey:@"org_lisp_definitions"])
286
-                {
287
-                    // The first expression didn't fire, try the second one.
288
-                    [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDef2_RE forKey:@"org_lisp_definitions"];
248
+        ts_query_cursor_exec(package_cursor, package_query, root_node);
249
+        uint32_t packagename_start, packagename_end, packagename_length;
250
+        
251
+        TSQueryMatch ts_match;
252
+        if (ts_query_cursor_next_match(package_cursor, &ts_match)) {
253
+            packagename_start = ts_node_start_byte(ts_match.captures[0].node);
254
+            packagename_end = ts_node_end_byte(ts_match.captures[0].node);
255
+            packagename_length = packagename_end - packagename_start;
256
+            packagename_buf = calloc(1 + packagename_length, sizeof(char));
257
+            if (packagename_buf) {
258
+                strncpy(packagename_buf, cstring_source + packagename_start, packagename_length);
259
+                [self addMatchesTo:moreAttributes fromCString: packagename_buf forKey:@"co_fwoar_java_package"];
260
+            } else {
261
+                goto fail;
262
+            }
263
+        }
264
+        
265
+        ts_query_cursor_exec(class_cursor, class_query, root_node);
266
+        while (ts_query_cursor_next_match(class_cursor, &ts_match)) {
267
+            if (ts_match.captures) {
268
+                uint32_t classname_start = ts_node_start_byte(ts_match.captures[0].node);
269
+                uint32_t classname_end = ts_node_end_byte(ts_match.captures[0].node);
270
+                uint32_t classname_length = classname_end - classname_start;
271
+                if (classname_buf) {
272
+                    free(classname_buf);
273
+                }
274
+                classname_buf = calloc(1 + (packagename_length + 1 + classname_length), sizeof(char));
275
+                if (classname_buf) {
276
+                    strncpy(classname_buf, cstring_source + packagename_start, packagename_length);
277
+                    classname_buf[packagename_length] = '.';
278
+                    strncpy(classname_buf + packagename_length + 1, cstring_source + classname_start, classname_length);
279
+                    [self addMatchesTo:moreAttributes fromCString: classname_buf forKey:@"co_fwoar_java_classes"];
280
+                    [self addMatchesTo:moreAttributes fromCString: classname_buf forKey:@"co_fwoar_java_definitions"];
281
+                } else {
282
+                    goto fail;
283
+                }
284
+            }
285
+        }
286
+        
287
+        ts_query_cursor_exec(class_cursor, interface_query, root_node);
288
+        while (ts_query_cursor_next_match(class_cursor, &ts_match)) {
289
+            if (ts_match.captures) {
290
+                uint32_t interfacename_start = ts_node_start_byte(ts_match.captures[0].node);
291
+                uint32_t interfacename_end = ts_node_end_byte(ts_match.captures[0].node);
292
+                uint32_t interfacename_length = interfacename_end - interfacename_start;
293
+                if (interfacename_buf) {
294
+                    free(interfacename_buf);
295
+                }
296
+                interfacename_buf = calloc(1 + (packagename_length + 1 + interfacename_length), sizeof(char));
297
+                if (interfacename_buf) {
298
+                    strncpy(interfacename_buf, cstring_source + packagename_start, packagename_length);
299
+                    interfacename_buf[packagename_length] = '.';
300
+                    strncpy(interfacename_buf + packagename_length + 1, cstring_source + interfacename_start, interfacename_length);
301
+                    [self addMatchesTo:moreAttributes fromCString: interfacename_buf forKey:@"co_fwoar_java_interfaces"];
302
+                    [self addMatchesTo:moreAttributes fromCString: interfacename_buf forKey:@"co_fwoar_java_definitions"];
303
+                } else {
304
+                    goto fail;
305
+                }
306
+            }
307
+        }
308
+        
309
+        ts_query_cursor_exec(class_cursor, method_query, root_node);
310
+        while (ts_query_cursor_next_match(class_cursor, &ts_match)) {
311
+            if (ts_match.captures) {
312
+                uint32_t classname_start = ts_node_start_byte(ts_match.captures[0].node);
313
+                uint32_t classname_end = ts_node_end_byte(ts_match.captures[0].node);
314
+                uint32_t classname_length = classname_end - classname_start;
315
+
316
+                uint32_t methodname_start = ts_node_start_byte(ts_match.captures[1].node);
317
+                uint32_t methodname_end = ts_node_end_byte(ts_match.captures[1].node);
318
+                uint32_t methodname_length = methodname_end - methodname_start;
319
+                if (methodname_buf) {
320
+                    free(methodname_buf);
321
+                }
322
+                methodname_buf = calloc(1 + (packagename_length + 1 + classname_length + 1 + methodname_length), sizeof(char));
323
+                if (methodname_buf) {
324
+                    strncpy(methodname_buf, cstring_source + packagename_start, packagename_length);
325
+                    methodname_buf[packagename_length] = '.';
326
+                    strncpy(methodname_buf + packagename_length + 1, cstring_source + classname_start, classname_length);
327
+                    methodname_buf[packagename_length + 1 + classname_length] = '.';
328
+                    strncpy(methodname_buf + packagename_length + 1 + classname_length + 1, cstring_source + methodname_start, methodname_length);
329
+                    // "((n+1)*m-1)
330
+                    uint32_t cur_offset = strlen(methodname_buf);
331
+                    uint32_t total_length = strlen(methodname_buf) + 1 /*null*/;
332
+                    for (uint16_t next = 2; next < ts_match.capture_count; next++) {
333
+                      uint32_t capture_start = ts_node_start_byte(ts_match.captures[next].node);
334
+                      uint32_t capture_end = ts_node_end_byte(ts_match.captures[next].node);
335
+                      uint32_t capture_length = capture_end - capture_start;
336
+                      total_length += capture_length;
337
+                    }
338
+                    methodname_buf = realloc(methodname_buf, total_length * sizeof(char));
339
+                    methodname_buf[total_length - 1] = '\0';
340
+
341
+                    for (uint16_t next = 2; next < ts_match.capture_count; next++) {
342
+                      uint32_t capture_start = ts_node_start_byte(ts_match.captures[next].node);
343
+                      uint32_t capture_end = ts_node_end_byte(ts_match.captures[next].node);
344
+                      uint32_t capture_length = capture_end - capture_start;
345
+                      strncpy(methodname_buf + cur_offset, cstring_source + capture_start, capture_length);
346
+                      cur_offset += capture_length;
347
+                    }
348
+                    if (cur_offset+1 != total_length) { NSLog(@"Something is wrong :( %u != %u", cur_offset+1, total_length); }
349
+                    [self addMatchesTo:moreAttributes fromCString: methodname_buf forKey:@"co_fwoar_java_methods"];
350
+                    [self addMatchesTo:moreAttributes fromCString: methodname_buf forKey:@"co_fwoar_java_definitions"];
351
+                } else {
352
+                    goto fail;
289 353
                 }
290
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefun_RE forKey:@"org_lisp_defuns"];
291
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefunsetf_RE forKey:@"org_lisp_defuns"];
292
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefmethod_RE forKey:@"org_lisp_defmethods"];
293
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefmethodsetf_RE forKey:@"org_lisp_defmethods"];
294
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefgeneric_RE forKey:@"org_lisp_defgenerics"];
295
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefgenericsetf_RE forKey:@"org_lisp_defgenerics"];
296
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefmacro_RE forKey:@"org_lisp_defmacros"];
297
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefvar_RE forKey:@"org_lisp_defvars"];
298
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefclass_RE forKey:@"org_lisp_defclasses"];
299
-                [self addMatchesTo:moreAttributes fromLine:theLine usingRE:LispDefstruct_RE forKey:@"org_lisp_defstructs"];
300 354
             }
301
-            
302 355
         }
303 356
         
304 357
         // Add the complete source code as metadata.
... ...
@@ -306,14 +359,30 @@ static NSStringEncoding PossibleSourceTextEncodings[] = {	NSUTF8StringEncoding,
306 359
         
307 360
         [inAttributes addEntriesFromDictionary:moreAttributes];
308 361
         theResult = YES;
362
+    fail:
309 363
         [theAutoreleasePool release];
310 364
     }
311 365
     @catch (NSException *localException)
312 366
     {
313
-        NSLog(@"Lisp Metadata Importer: Could not process file '%@' (Exception: %@)", inPathToFile, localException);
367
+        NSLog(@"Tree Sitter (java) Metadata Importer: Could not process file '%@' (Exception: %@)", inPathToFile, localException);
314 368
     }
315 369
     @finally
316 370
     {
371
+        ts_query_cursor_delete(class_cursor);
372
+        ts_query_cursor_delete(package_cursor);
373
+        if (packagename_buf) {
374
+            free(packagename_buf);
375
+        }
376
+        if (classname_buf) {
377
+            free(classname_buf);
378
+        }
379
+        if (interfacename_buf) {
380
+            free(interfacename_buf);
381
+        }
382
+        if (methodname_buf) {
383
+            free(methodname_buf);
384
+        }
385
+        ts_parser_delete(ts_parser);
317 386
     }
318 387
     return(theResult);
319 388
 }
320 389
new file mode 120000
... ...
@@ -0,0 +1 @@
1
+../Source/tree-sitter/lib/include/tree_sitter
0 2
\ No newline at end of file
1 3
new file mode 120000
... ...
@@ -0,0 +1 @@
1
+../Source/tree-sitter/lib/src/unicode/
0 2
\ No newline at end of file