1
0
forked from VimPlug/jedi

context -> value

This commit is contained in:
Dave Halter
2019-08-15 01:23:06 +02:00
parent 9e23f4d67b
commit ad4f546aca
68 changed files with 1931 additions and 1931 deletions
+43 -43
View File
@@ -24,21 +24,21 @@ from jedi.inference import analysis
from jedi.inference import flow_analysis
from jedi.inference.arguments import TreeArguments
from jedi.inference import helpers
from jedi.inference.context import iterable
from jedi.inference.value import iterable
from jedi.inference.filters import get_global_filters
from jedi.inference.names import TreeNameDefinition
from jedi.inference.base_value import ContextSet, NO_CONTEXTS
from jedi.parser_utils import is_scope, get_parent_scope
from jedi.inference.gradual.conversion import convert_contexts
from jedi.inference.gradual.conversion import convert_values
class NameFinder(object):
def __init__(self, infer_state, context, name_context, name_or_str,
def __init__(self, infer_state, value, name_value, name_or_str,
position=None, analysis_errors=True):
self._infer_state = infer_state
# Make sure that it's not just a syntax tree node.
self._context = context
self._name_context = name_context
self._value = value
self._name_value = name_value
self._name = name_or_str
if isinstance(name_or_str, tree.Name):
self._string_name = name_or_str.value
@@ -56,8 +56,8 @@ class NameFinder(object):
names = self.filter_name(filters)
if self._found_predefined_types is not None and names:
check = flow_analysis.reachability_check(
context=self._context,
context_scope=self._context.tree_node,
value=self._value,
value_scope=self._value.tree_node,
node=self._name,
)
if check is flow_analysis.UNREACHABLE:
@@ -72,11 +72,11 @@ class NameFinder(object):
if isinstance(self._name, tree.Name):
if attribute_lookup:
analysis.add_attribute_error(
self._name_context, self._context, self._name)
self._name_value, self._value, self._name)
else:
message = ("NameError: name '%s' is not defined."
% self._string_name)
analysis.add(self._name_context, 'name-error', self._name, message)
analysis.add(self._name_value, 'name-error', self._name, message)
return types
@@ -98,7 +98,7 @@ class NameFinder(object):
position = self._position
# For functions and classes the defaults don't belong to the
# function and get inferred in the context before the function. So
# function and get inferred in the value before the function. So
# make sure to exclude the function/class name.
if origin_scope is not None:
ancestor = search_ancestor(origin_scope, 'funcdef', 'classdef', 'lambdef')
@@ -114,16 +114,16 @@ class NameFinder(object):
if lambdef is None or position < lambdef.children[-2].start_pos:
position = ancestor.start_pos
return get_global_filters(self._infer_state, self._context, position, origin_scope)
return get_global_filters(self._infer_state, self._value, position, origin_scope)
else:
return self._get_context_filters(origin_scope)
return self._get_value_filters(origin_scope)
def _get_context_filters(self, origin_scope):
for f in self._context.get_filters(False, self._position, origin_scope=origin_scope):
def _get_value_filters(self, origin_scope):
for f in self._value.get_filters(False, self._position, origin_scope=origin_scope):
yield f
# This covers the case where a stub files are incomplete.
if self._context.is_stub():
for c in convert_contexts(ContextSet({self._context})):
if self._value.is_stub():
for c in convert_values(ContextSet({self._value})):
for f in c.get_filters():
yield f
@@ -135,13 +135,13 @@ class NameFinder(object):
names = []
# This paragraph is currently needed for proper branch type inference
# (static analysis).
if self._context.predefined_names and isinstance(self._name, tree.Name):
if self._value.predefined_names and isinstance(self._name, tree.Name):
node = self._name
while node is not None and not is_scope(node):
node = node.parent
if node.type in ("if_stmt", "for_stmt", "comp_for", 'sync_comp_for'):
try:
name_dict = self._context.predefined_names[node]
name_dict = self._value.predefined_names[node]
types = name_dict[self._string_name]
except KeyError:
continue
@@ -167,7 +167,7 @@ class NameFinder(object):
break
debug.dbg('finder.filter_name %s in (%s): %s@%s',
self._string_name, self._context, names, self._position)
self._string_name, self._value, names, self._position)
return list(names)
def _check_getattr(self, inst):
@@ -187,33 +187,33 @@ class NameFinder(object):
return inst.execute_function_slots(names, name)
def _names_to_types(self, names, attribute_lookup):
contexts = ContextSet.from_sets(name.infer() for name in names)
values = ContextSet.from_sets(name.infer() for name in names)
debug.dbg('finder._names_to_types: %s -> %s', names, contexts)
if not names and self._context.is_instance() and not self._context.is_compiled():
debug.dbg('finder._names_to_types: %s -> %s', names, values)
if not names and self._value.is_instance() and not self._value.is_compiled():
# handling __getattr__ / __getattribute__
return self._check_getattr(self._context)
return self._check_getattr(self._value)
# Add isinstance and other if/assert knowledge.
if not contexts and isinstance(self._name, tree.Name) and \
not self._name_context.is_instance() and not self._context.is_compiled():
if not values and isinstance(self._name, tree.Name) and \
not self._name_value.is_instance() and not self._value.is_compiled():
flow_scope = self._name
base_nodes = [self._name_context.tree_node]
base_nodes = [self._name_value.tree_node]
if any(b.type in ('comp_for', 'sync_comp_for') for b in base_nodes):
return contexts
return values
while True:
flow_scope = get_parent_scope(flow_scope, include_flows=True)
n = _check_flow_information(self._name_context, flow_scope,
n = _check_flow_information(self._name_value, flow_scope,
self._name, self._position)
if n is not None:
return n
if flow_scope in base_nodes:
break
return contexts
return values
def _check_flow_information(context, flow, search_name, pos):
def _check_flow_information(value, flow, search_name, pos):
""" Try to find out the type of a variable just with the information that
is given by the flows: e.g. It is also responsible for assert checks.::
@@ -241,7 +241,7 @@ def _check_flow_information(context, flow, search_name, pos):
for name in names:
ass = search_ancestor(name, 'assert_stmt')
if ass is not None:
result = _check_isinstance_type(context, ass.assertion, search_name)
result = _check_isinstance_type(value, ass.assertion, search_name)
if result is not None:
return result
@@ -249,11 +249,11 @@ def _check_flow_information(context, flow, search_name, pos):
potential_ifs = [c for c in flow.children[1::4] if c != ':']
for if_test in reversed(potential_ifs):
if search_name.start_pos > if_test.end_pos:
return _check_isinstance_type(context, if_test, search_name)
return _check_isinstance_type(value, if_test, search_name)
return result
def _check_isinstance_type(context, element, search_name):
def _check_isinstance_type(value, element, search_name):
try:
assert element.type in ('power', 'atom_expr')
# this might be removed if we analyze and, etc
@@ -265,26 +265,26 @@ def _check_isinstance_type(context, element, search_name):
# arglist stuff
arglist = trailer.children[1]
args = TreeArguments(context.infer_state, context, arglist, trailer)
args = TreeArguments(value.infer_state, value, arglist, trailer)
param_list = list(args.unpack())
# Disallow keyword arguments
assert len(param_list) == 2
(key1, lazy_context_object), (key2, lazy_context_cls) = param_list
(key1, lazy_value_object), (key2, lazy_value_cls) = param_list
assert key1 is None and key2 is None
call = helpers.call_of_leaf(search_name)
is_instance_call = helpers.call_of_leaf(lazy_context_object.data)
is_instance_call = helpers.call_of_leaf(lazy_value_object.data)
# Do a simple get_code comparison. They should just have the same code,
# and everything will be all right.
normalize = context.infer_state.grammar._normalize
normalize = value.infer_state.grammar._normalize
assert normalize(is_instance_call) == normalize(call)
except AssertionError:
return None
context_set = NO_CONTEXTS
for cls_or_tup in lazy_context_cls.infer():
value_set = NO_CONTEXTS
for cls_or_tup in lazy_value_cls.infer():
if isinstance(cls_or_tup, iterable.Sequence) and cls_or_tup.array_type == 'tuple':
for lazy_context in cls_or_tup.py__iter__():
context_set |= lazy_context.infer().execute_with_values()
for lazy_value in cls_or_tup.py__iter__():
value_set |= lazy_value.infer().execute_with_values()
else:
context_set |= cls_or_tup.execute_with_values()
return context_set
value_set |= cls_or_tup.execute_with_values()
return value_set