1313import warnings
1414import sys
1515
16- from jedi ._compatibility import unicode
1716from jedi .parser import load_grammar
1817from jedi .parser import tree
19- from jedi .parser .fast import FastParser
18+ from jedi .parser .diff import FastParser
2019from jedi .parser .utils import save_parser
2120from jedi import debug
2221from jedi import settings
3433from jedi .evaluate .helpers import get_module_names
3534from jedi .evaluate .sys_path import get_venv_path
3635from jedi .evaluate .iterable import unpack_tuple_to_dict
36+ from jedi .evaluate .filters import TreeNameDefinition
3737
3838# Jedi uses lots and lots of recursion. By setting this a little bit higher, we
3939# can remove some "maximum recursion depth" errors.
@@ -105,12 +105,8 @@ def __init__(self, source=None, line=None, column=None, path=None,
105105
106106 if source is None :
107107 # TODO add a better warning than the traceback!
108- try :
109- with open (path ) as f :
110- source = f .read ()
111- except UnicodeDecodeError :
112- with open (path , encoding = encoding ) as f :
113- source = f .read ()
108+ with open (path , 'rb' ) as f :
109+ source = f .read ()
114110
115111 self ._source = common .source_to_unicode (source , encoding )
116112 self ._code_lines = common .splitlines (self ._source )
@@ -135,15 +131,20 @@ def __init__(self, source=None, line=None, column=None, path=None,
135131 self ._evaluator = Evaluator (self ._grammar , sys_path = sys_path )
136132 debug .speed ('init' )
137133
138- def _get_module (self ):
134+ @cache .memoize_method
135+ def _get_module_node (self ):
139136 cache .invalidate_star_import_cache (self ._path )
140137 parser = FastParser (self ._grammar , self ._source , self .path )
141138 save_parser (self .path , parser , pickling = False )
142139
143- module = self ._evaluator .wrap (parser .module )
144- imports .add_module (self ._evaluator , unicode (module .name ), module )
145140 return parser .module
146141
142+ @cache .memoize_method
143+ def _get_module (self ):
144+ module = er .ModuleContext (self ._evaluator , self ._get_module_node ())
145+ imports .add_module (self ._evaluator , module .name .string_name , module )
146+ return module
147+
147148 @property
148149 def source_path (self ):
149150 """
@@ -186,12 +187,15 @@ def goto_definitions(self):
186187
187188 :rtype: list of :class:`classes.Definition`
188189 """
189- leaf = self ._get_module ().name_for_position (self ._pos )
190+ module_node = self ._get_module_node ()
191+ leaf = module_node .name_for_position (self ._pos )
190192 if leaf is None :
191- leaf = self . _get_module () .get_leaf_for_position (self ._pos )
193+ leaf = module_node .get_leaf_for_position (self ._pos )
192194 if leaf is None :
193195 return []
194- definitions = helpers .evaluate_goto_definition (self ._evaluator , leaf )
196+
197+ context = self ._evaluator .create_context (self ._get_module (), leaf )
198+ definitions = helpers .evaluate_goto_definition (self ._evaluator , context , leaf )
195199
196200 names = [s .name for s in definitions ]
197201 defs = [classes .Definition (self ._evaluator , name ) for name in names ]
@@ -211,11 +215,9 @@ def goto_assignments(self, follow_imports=False):
211215 """
212216 def filter_follow_imports (names ):
213217 for name in names :
214- definition = name .get_definition ()
215- if definition .type in ('import_name' , 'import_from' ):
216- imp = imports .ImportWrapper (self ._evaluator , name )
217- for name in filter_follow_imports (imp .follow (is_goto = True )):
218- yield name
218+ if isinstance (name , (imports .ImportName , TreeNameDefinition )):
219+ for context in name .infer ():
220+ yield context .name
219221 else :
220222 yield name
221223
@@ -230,10 +232,11 @@ def _goto(self):
230232 """
231233 Used for goto_assignments and usages.
232234 """
233- name = self ._get_module ().name_for_position (self ._pos )
235+ name = self ._get_module_node ().name_for_position (self ._pos )
234236 if name is None :
235237 return []
236- return list (self ._evaluator .goto (name ))
238+ context = self ._evaluator .create_context (self ._get_module (), name )
239+ return list (self ._evaluator .goto (context , name ))
237240
238241 def usages (self , additional_module_paths = ()):
239242 """
@@ -249,37 +252,33 @@ def usages(self, additional_module_paths=()):
249252 temp , settings .dynamic_flow_information = \
250253 settings .dynamic_flow_information , False
251254 try :
252- user_stmt = self ._get_module ().get_statement_for_position (self ._pos )
253- definitions = self ._goto ()
254- if not definitions and isinstance (user_stmt , tree .Import ):
255+ module_node = self ._get_module_node ()
256+ user_stmt = module_node .get_statement_for_position (self ._pos )
257+ definition_names = self ._goto ()
258+ if not definition_names and isinstance (user_stmt , tree .Import ):
255259 # For not defined imports (goto doesn't find something, we take
256260 # the name as a definition. This is enough, because every name
257261 # points to it.
258262 name = user_stmt .name_for_position (self ._pos )
259263 if name is None :
260264 # Must be syntax
261265 return []
262- definitions = [name ]
266+ definition_names = [TreeNameDefinition ( self . _get_module (), name ) ]
263267
264- if not definitions :
268+ if not definition_names :
265269 # Without a definition for a name we cannot find references.
266270 return []
267271
268- if not isinstance (user_stmt , tree .Import ):
269- # import case is looked at with add_import_name option
270- definitions = usages .usages_add_import_modules (self ._evaluator ,
271- definitions )
272-
273- module = set ([d .get_parent_until () for d in definitions ])
274- module .add (self ._get_module ())
275- names = usages .usages (self ._evaluator , definitions , module )
272+ definition_names = usages .resolve_potential_imports (self ._evaluator ,
273+ definition_names )
276274
277- for d in set (definitions ):
278- names .append (classes .Definition (self ._evaluator , d ))
275+ modules = set ([d .get_root_context () for d in definition_names ])
276+ modules .add (self ._get_module ())
277+ definitions = usages .usages (self ._evaluator , definition_names , modules )
279278 finally :
280279 settings .dynamic_flow_information = temp
281280
282- return helpers .sorted_definitions (set (names ))
281+ return helpers .sorted_definitions (set (definitions ))
283282
284283 def call_signatures (self ):
285284 """
@@ -298,13 +297,18 @@ def call_signatures(self):
298297 :rtype: list of :class:`classes.CallSignature`
299298 """
300299 call_signature_details = \
301- helpers .get_call_signature_details (self ._get_module (), self ._pos )
300+ helpers .get_call_signature_details (self ._get_module_node (), self ._pos )
302301 if call_signature_details is None :
303302 return []
304303
304+ context = self ._evaluator .create_context (
305+ self ._get_module (),
306+ call_signature_details .bracket_leaf
307+ )
305308 with common .scale_speed_settings (settings .scale_call_signatures ):
306309 definitions = helpers .cache_call_signatures (
307310 self ._evaluator ,
311+ context ,
308312 call_signature_details .bracket_leaf ,
309313 self ._code_lines ,
310314 self ._pos
@@ -319,27 +323,29 @@ def call_signatures(self):
319323
320324 def _analysis (self ):
321325 self ._evaluator .is_analysis = True
322- self ._evaluator .analysis_modules = [self ._get_module ()]
326+ module_node = self ._get_module_node ()
327+ self ._evaluator .analysis_modules = [module_node ]
323328 try :
324- for node in self ._get_module ().nodes_to_execute ():
329+ for node in module_node .nodes_to_execute ():
330+ context = self ._get_module ().create_context (node )
325331 if node .type in ('funcdef' , 'classdef' ):
326- if node . type == 'classdef' :
327- continue
328- raise NotImplementedError
329- er . Function (self ._evaluator , node ). get_decorated_func ( )
332+ # TODO This is stupid, should be private
333+ from jedi . evaluate . finder import _name_to_types
334+ # Resolve the decorators.
335+ _name_to_types (self ._evaluator , context , node . children [ 1 ] )
330336 elif isinstance (node , tree .Import ):
331337 import_names = set (node .get_defined_names ())
332338 if node .is_nested ():
333339 import_names |= set (path [- 1 ] for path in node .paths ())
334340 for n in import_names :
335- imports .ImportWrapper ( self . _evaluator , n ). follow ( )
341+ imports .infer_import ( context , n )
336342 elif node .type == 'expr_stmt' :
337- types = self . _evaluator . eval_element (node )
343+ types = context . eval_node (node )
338344 for testlist in node .children [:- 1 :2 ]:
339345 # Iterate tuples.
340346 unpack_tuple_to_dict (self ._evaluator , types , testlist )
341347 else :
342- try_iter_content (self ._evaluator .goto_definitions (node ))
348+ try_iter_content (self ._evaluator .goto_definitions (context , node ))
343349 self ._evaluator .reset_recursion_limitations ()
344350
345351 ana = [a for a in self ._evaluator .analysis if self .path == a .path ]
@@ -386,11 +392,13 @@ def __init__(self, source, namespaces, **kwds):
386392 super (Interpreter , self ).__init__ (source , ** kwds )
387393 self .namespaces = namespaces
388394
389- parser_module = super (Interpreter , self )._get_module ()
390- self ._module = interpreter .MixedModule (self ._evaluator , parser_module , self .namespaces )
391-
392395 def _get_module (self ):
393- return self ._module
396+ parser_module = super (Interpreter , self )._get_module_node ()
397+ return interpreter .MixedModuleContext (
398+ self ._evaluator ,
399+ parser_module ,
400+ self .namespaces
401+ )
394402
395403
396404def defined_names (source , path = None , encoding = 'utf-8' ):
@@ -430,13 +438,21 @@ def names(source=None, path=None, encoding='utf-8', all_scopes=False,
430438 ``definitions=True``. E.g. ``a = b`` returns ``b``.
431439 """
432440 def def_ref_filter (_def ):
433- is_def = _def .is_definition ()
441+ is_def = _def ._name . tree_name . is_definition ()
434442 return definitions and is_def or references and not is_def
435443
436444 # Set line/column to a random position, because they don't matter.
437445 script = Script (source , line = 1 , column = 0 , path = path , encoding = encoding )
438- defs = [classes .Definition (script ._evaluator , name_part )
439- for name_part in get_module_names (script ._get_module (), all_scopes )]
446+ module_context = script ._get_module ()
447+ defs = [
448+ classes .Definition (
449+ script ._evaluator ,
450+ TreeNameDefinition (
451+ module_context .create_context (name .parent ),
452+ name
453+ )
454+ ) for name in get_module_names (script ._get_module_node (), all_scopes )
455+ ]
440456 return sorted (filter (def_ref_filter , defs ), key = lambda x : (x .line , x .column ))
441457
442458
0 commit comments