@@ -45,9 +45,11 @@ def search_file(self, file_path: str, params: SearchParameters) -> List[SearchRe
4545 parser = get_parser (lang_name )
4646 tree = parser .parse (source_code .encode ('utf-8' ))
4747
48- # For Phase 1, we'll hardcode the function-calls pattern
48+ # Route to appropriate search method
4949 if params .search_type == "function-calls" :
5050 return self ._search_function_calls (file_path , source_code , tree , params , lang_name )
51+ elif params .search_type == "symbol-definitions" :
52+ return self ._search_symbol_definitions (file_path , source_code , tree , params , lang_name )
5153
5254 return []
5355
@@ -189,6 +191,144 @@ def _search_function_calls(self, file_path: str, source_code: str, tree: Any,
189191
190192 return results
191193
194+ def _search_symbol_definitions (self , file_path : str , source_code : str , tree : Any ,
195+ params : SearchParameters , lang_name : str ) -> List [SearchResult ]:
196+ """Search for symbol definitions (classes, functions, variables) in the parsed tree."""
197+ results = []
198+
199+ # Define query patterns for different languages
200+ patterns = {
201+ 'python' : '''
202+ ; Function definitions
203+ (function_definition
204+ name: (identifier) @function_name
205+ ) @function_def
206+
207+ ; Class definitions
208+ (class_definition
209+ name: (identifier) @class_name
210+ ) @class_def
211+
212+ ; Variable assignments
213+ (assignment
214+ left: (identifier) @variable_name
215+ ) @variable_def
216+ ''' ,
217+ 'javascript' : '''
218+ ; Function declarations
219+ (function_declaration
220+ name: (identifier) @function_name
221+ ) @function_def
222+
223+ ; Class declarations
224+ (class_declaration
225+ name: (identifier) @class_name
226+ ) @class_def
227+
228+ ; Variable declarations
229+ (variable_declaration
230+ (variable_declarator
231+ name: (identifier) @variable_name
232+ )
233+ ) @variable_def
234+
235+ ; Const declarations
236+ (lexical_declaration
237+ (variable_declarator
238+ name: (identifier) @variable_name
239+ )
240+ ) @const_def
241+ ''' ,
242+ 'typescript' : '''
243+ ; Function declarations
244+ (function_declaration
245+ name: (identifier) @function_name
246+ ) @function_def
247+
248+ ; Class declarations
249+ (class_declaration
250+ name: (identifier) @class_name
251+ ) @class_def
252+
253+ ; Interface declarations
254+ (interface_declaration
255+ name: (type_identifier) @interface_name
256+ ) @interface_def
257+
258+ ; Type alias declarations
259+ (type_alias_declaration
260+ name: (type_identifier) @type_name
261+ ) @type_def
262+
263+ ; Variable declarations
264+ (variable_declaration
265+ (variable_declarator
266+ name: (identifier) @variable_name
267+ )
268+ ) @variable_def
269+
270+ ; Const declarations
271+ (lexical_declaration
272+ (variable_declarator
273+ name: (identifier) @variable_name
274+ )
275+ ) @const_def
276+ '''
277+ }
278+
279+ pattern = patterns .get (lang_name )
280+ if not pattern :
281+ return []
282+
283+ # Compile and execute query
284+ query = self ._get_compiled_query (lang_name , pattern )
285+ captures = query .captures (tree .root_node )
286+
287+ source_lines = source_code .splitlines ()
288+
289+ for node , capture_name in captures :
290+ if capture_name .endswith ('_def' ):
291+ # Check if this symbol name matches our target
292+ symbol_text = source_code [node .start_byte :node .end_byte ]
293+
294+ # For symbol definitions, we want to check if the target appears in the symbol
295+ if params .target in symbol_text :
296+ start_line = node .start_point [0 ] + 1
297+ end_line = node .end_point [0 ] + 1
298+
299+ # Get context lines
300+ context_before = []
301+ context_after = []
302+ if params .include_context :
303+ start_ctx = max (0 , start_line - 1 - params .context_lines )
304+ end_ctx = min (len (source_lines ), end_line + params .context_lines )
305+ context_before = source_lines [start_ctx :start_line - 1 ]
306+ context_after = source_lines [end_line :end_ctx ]
307+
308+ # Determine symbol type from capture name
309+ symbol_type = capture_name .replace ('_def' , '' ).replace ('_name' , '' )
310+
311+ result = SearchResult (
312+ file_path = file_path ,
313+ start_line = start_line ,
314+ end_line = end_line ,
315+ match_text = symbol_text ,
316+ context_before = context_before ,
317+ context_after = context_after ,
318+ metadata = {
319+ "search_type" : params .search_type ,
320+ "target" : params .target ,
321+ "symbol_type" : symbol_type
322+ },
323+ language = lang_name
324+ )
325+ results .append (result )
326+
327+ if len (results ) >= params .max_results :
328+ break
329+
330+ return results
331+
192332 def _get_compiled_query (self , language : str , pattern : str ) -> Query :
193333 """Get or compile a tree-sitter query."""
194334 cache_key = f"{ language } :{ hash (pattern )} "
0 commit comments