11from pathlib import Path
22from typing import Optional
33
4- from tree_sitter import Language , Node , Parser , Point , QueryCursor
4+ from tree_sitter import Language , Node , Parser , Point , Query , QueryCursor
55from api .entities .entity import Entity
66from api .entities .file import File
77from abc import ABC , abstractmethod
@@ -11,11 +11,20 @@ class AbstractAnalyzer(ABC):
1111 def __init__ (self , language : Language ) -> None :
1212 self .language = language
1313 self .parser = Parser (language )
14+ # Memoise compiled queries; tree-sitter query compilation is ~370us
15+ # each and adds up to seconds on large repos.
16+ self ._query_cache : dict [str , Query ] = {}
17+
18+ def _get_query (self , pattern : str ) -> Query :
19+ q = self ._query_cache .get (pattern )
20+ if q is None :
21+ q = Query (self .language , pattern )
22+ self ._query_cache [pattern ] = q
23+ return q
1424
1525 def _captures (self , pattern : str , node : Node ) -> dict :
1626 """Run a tree-sitter query and return captures dict."""
17- query = self .language .query (pattern )
18- cursor = QueryCursor (query )
27+ cursor = QueryCursor (self ._get_query (pattern ))
1928 return cursor .captures (node )
2029
2130 def find_parent (self , node : Node , parent_types : list ) -> Node :
0 commit comments