1
0
forked from VimPlug/jedi

Fix properties.

This commit is contained in:
Dave Halter
2016-11-16 21:16:12 +01:00
parent 21e17b7762
commit ba03f1dcb9
4 changed files with 80 additions and 36 deletions
+4 -1
View File
@@ -364,7 +364,7 @@ class CompiledObjectFilter(AbstractFilter):
# lookups possible without having the actual attribute. However # lookups possible without having the actual attribute. However
# this makes proper completion possible. # this makes proper completion possible.
return [FakeName(name, create(self._evaluator, None), is_definition=True)] return [FakeName(name, create(self._evaluator, None), is_definition=True)]
return [self.name_class(self._evaluator, self._compiled_obj, name)] return [self._create(name)]
def values(self): def values(self):
obj = self._compiled_obj.obj obj = self._compiled_obj.obj
@@ -380,6 +380,9 @@ class CompiledObjectFilter(AbstractFilter):
names += filter.values() names += filter.values()
return names return names
def _create(self, name):
return self.name_class(self._evaluator, self._compiled_obj, name)
def dotted_from_fs_path(fs_path, sys_path): def dotted_from_fs_path(fs_path, sys_path):
""" """
+1 -1
View File
@@ -59,7 +59,7 @@ class TreeNameDefinition(ContextName):
def infer(self): def infer(self):
# Refactor this, should probably be here. # Refactor this, should probably be here.
from jedi.evaluate.finder import _name_to_types from jedi.evaluate.finder import _name_to_types
return _name_to_types(self.parent_context.evaluator, self.parent_context, self.tree_name, None) return _name_to_types(self.parent_context.evaluator, self.parent_context, self.tree_name)
class ParamName(ContextName): class ParamName(ContextName):
+13 -8
View File
@@ -22,6 +22,7 @@ from jedi import debug
from jedi.common import unite from jedi.common import unite
from jedi import settings from jedi import settings
from jedi.evaluate import representation as er from jedi.evaluate import representation as er
from jedi.evaluate.instance import AbstractInstanceContext
from jedi.evaluate import dynamic from jedi.evaluate import dynamic
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import docstrings from jedi.evaluate import docstrings
@@ -32,9 +33,8 @@ from jedi.evaluate import analysis
from jedi.evaluate import flow_analysis from jedi.evaluate import flow_analysis
from jedi.evaluate import param from jedi.evaluate import param
from jedi.evaluate import helpers from jedi.evaluate import helpers
from jedi.evaluate.instance import AbstractInstanceContext
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import memoize_default
from jedi.evaluate.filters import get_global_filters from jedi.evaluate.filters import get_global_filters, ContextName
def filter_after_position(names, position, origin=None): def filter_after_position(names, position, origin=None):
@@ -321,7 +321,8 @@ class NameFinder(object):
for name in names: for name in names:
new_types = name.infer() new_types = name.infer()
if isinstance(self.context, (er.ClassContext, er.Instance)) and attribute_lookup: if isinstance(self.context, (er.ClassContext, AbstractInstanceContext)) \
and attribute_lookup:
types |= set(self._resolve_descriptors(name, new_types)) types |= set(self._resolve_descriptors(name, new_types))
else: else:
types |= set(new_types) types |= set(new_types)
@@ -334,6 +335,10 @@ class NameFinder(object):
return types return types
def _resolve_descriptors(self, name, types): def _resolve_descriptors(self, name, types):
if not isinstance(name, ContextName):
# Compiled names and other stuff should just be ignored when it
# comes to descriptors.
return types
# The name must not be in the dictionary, but part of the class # The name must not be in the dictionary, but part of the class
# definition. __get__ is only called if the descriptor is defined in # definition. __get__ is only called if the descriptor is defined in
# the class dictionary. # the class dictionary.
@@ -353,7 +358,7 @@ class NameFinder(object):
@memoize_default(set(), evaluator_is_first_arg=True) @memoize_default(set(), evaluator_is_first_arg=True)
def _name_to_types(evaluator, context, name, scope): def _name_to_types(evaluator, context, name):
types = [] types = []
node = name.get_definition() node = name.get_definition()
if node.isinstance(tree.ForStmt): if node.isinstance(tree.ForStmt):
@@ -370,7 +375,7 @@ def _name_to_types(evaluator, context, name, scope):
types = check_tuple_assignments(evaluator, for_types, name) types = check_tuple_assignments(evaluator, for_types, name)
elif isinstance(node, tree.Param): elif isinstance(node, tree.Param):
return set() # TODO remove return set() # TODO remove
types = _eval_param(evaluator, context, node, scope) types = _eval_param(evaluator, context, node)
elif node.isinstance(tree.ExprStmt): elif node.isinstance(tree.ExprStmt):
types = _remove_statements(evaluator, context, node, name) types = _remove_statements(evaluator, context, node, name)
elif node.isinstance(tree.WithStmt): elif node.isinstance(tree.WithStmt):
@@ -423,10 +428,10 @@ def _apply_decorators(evaluator, context, node):
for dec in reversed(node.get_decorators()): for dec in reversed(node.get_decorators()):
debug.dbg('decorator: %s %s', dec, values) debug.dbg('decorator: %s %s', dec, values)
dec_values = context.eval_node(dec.children[1]) dec_values = context.eval_node(dec.children[1])
trailer = dec.children[2:-1] trailer_nodes = dec.children[2:-1]
if trailer: if trailer_nodes:
# Create a trailer and evaluate it. # Create a trailer and evaluate it.
trailer = tree.Node('trailer', trailer) trailer = tree.Node('trailer', trailer_nodes)
trailer.parent = dec trailer.parent = dec
dec_values = evaluator.eval_trailer(context, dec_values, trailer) dec_values = evaluator.eval_trailer(context, dec_values, trailer)
+62 -26
View File
@@ -142,24 +142,10 @@ class AbstractInstanceContext(Context):
def name(self): def name(self):
pass pass
def __repr__(self):
return "<%s of %s(%s)>" % (self.__class__.__name__, self.class_context,
self.var_args)
class CompiledInstance(AbstractInstanceContext):
@property
def name(self):
return compiled.CompiledContextName(self, self.class_context.name.string_name)
class TreeInstance(AbstractInstanceContext):
@property
def name(self):
return filters.ContextName(self, self.class_context.name.tree_name)
@memoize_default() @memoize_default()
def create_instance_context(self, class_context, node): def create_instance_context(self, class_context, node):
if node.parent.type in ('funcdef', 'classdef'):
node = node.parent
scope = node.get_parent_scope() scope = node.get_parent_scope()
if scope == class_context.classdef: if scope == class_context.classdef:
return class_context return class_context
@@ -183,6 +169,28 @@ class TreeInstance(AbstractInstanceContext):
raise NotImplementedError raise NotImplementedError
return class_context return class_context
def __repr__(self):
return "<%s of %s(%s)>" % (self.__class__.__name__, self.class_context,
self.var_args)
class CompiledInstance(AbstractInstanceContext):
@property
def name(self):
return compiled.CompiledContextName(self, self.class_context.name.string_name)
def create_instance_context(self, class_context, node):
if node.get_parent_scope().type == 'classdef':
return class_context
else:
return super(CompiledInstance, self).create_instance_context(class_context, node)
class TreeInstance(AbstractInstanceContext):
@property
def name(self):
return filters.ContextName(self, self.class_context.name.tree_name)
class AnonymousInstance(TreeInstance): class AnonymousInstance(TreeInstance):
def __init__(self, evaluator, parent_context, class_context): def __init__(self, evaluator, parent_context, class_context):
@@ -194,7 +202,22 @@ class AnonymousInstance(TreeInstance):
) )
class CompiledInstanceName(compiled.CompiledName):
def __init__(self, evaluator, instance, parent_context, name):
super(CompiledInstanceName, self).__init__(evaluator, parent_context, name)
self._instance = instance
def infer(self):
for v in super(CompiledInstanceName, self).infer():
if isinstance(v, er.FunctionContext):
yield BoundMethod(self._instance, self.parent_context, v)
else:
yield v
class CompiledInstanceClassFilter(compiled.CompiledObjectFilter): class CompiledInstanceClassFilter(compiled.CompiledObjectFilter):
name_class = CompiledInstanceName
def __init__(self, evaluator, instance, compiled_object): def __init__(self, evaluator, instance, compiled_object):
super(CompiledInstanceClassFilter, self).__init__( super(CompiledInstanceClassFilter, self).__init__(
evaluator, evaluator,
@@ -203,10 +226,8 @@ class CompiledInstanceClassFilter(compiled.CompiledObjectFilter):
) )
self._instance = instance self._instance = instance
def _filter(self, names): def _create(self, name):
names = super(CompiledInstanceClassFilter, self)._filter(names) return self.name_class(self._evaluator, self._instance, self._compiled_obj, name)
return [get_instance_el(self._evaluator, self._instance, name, True)
for name in names]
class BoundMethod(Context): class BoundMethod(Context):
@@ -252,6 +273,20 @@ class LazyInstanceName(filters.TreeNameDefinition):
return self._instance.create_instance_context(self._class_context, self.tree_name) return self._instance.create_instance_context(self._class_context, self.tree_name)
class LazyInstanceName(filters.TreeNameDefinition):
"""
This name calculates the parent_context lazily.
"""
def __init__(self, instance, class_context, tree_name):
self._instance = instance
self._class_context = class_context
self.tree_name = tree_name
@property
def parent_context(self):
return self._instance.create_instance_context(self._class_context, self.tree_name)
class LazyInstanceClassName(LazyInstanceName): class LazyInstanceClassName(LazyInstanceName):
def infer(self): def infer(self):
for v in super(LazyInstanceClassName, self).infer(): for v in super(LazyInstanceClassName, self).infer():
@@ -289,9 +324,6 @@ class InstanceClassFilter(filters.ParserTreeFilter):
names = super(InstanceClassFilter, self)._filter(names) names = super(InstanceClassFilter, self)._filter(names)
return [name for name in names if self._access_possible(name)] return [name for name in names if self._access_possible(name)]
def _check_flows(self, names):
return names
def _convert_names(self, names): def _convert_names(self, names):
return [self.name_class(self.context, self._class_context, name) for name in names] return [self.name_class(self.context, self._class_context, name) for name in names]
@@ -303,9 +335,10 @@ class SelfNameFilter(InstanceClassFilter):
names = self._filter_self_names(names) names = self._filter_self_names(names)
if isinstance(self._parser_scope, compiled.CompiledObject): if isinstance(self._parser_scope, compiled.CompiledObject):
# This would be for builtin skeletons, which are not yet supported. # This would be for builtin skeletons, which are not yet supported.
return [] return list(names)
start, end = self._parser_scope.start_pos, self._parser_scope.end_pos else:
return [n for n in names if start < n.start_pos < end] start, end = self._parser_scope.start_pos, self._parser_scope.end_pos
return [n for n in names if start < n.start_pos < end]
def _filter_self_names(self, names): def _filter_self_names(self, names):
for name in names: for name in names:
@@ -323,6 +356,9 @@ class SelfNameFilter(InstanceClassFilter):
name = init_execution.name_for_position(name.start_pos) name = init_execution.name_for_position(name.start_pos)
yield name yield name
def _check_flows(self, names):
return names
class ParamArguments(object): class ParamArguments(object):
""" """