forked from VimPlug/jedi
Now overloaded functions exist, but the matching doesn't work, yet
This commit is contained in:
@@ -104,12 +104,24 @@ class FunctionContext(use_metaclass(CachedMetaClass, AbstractFunction)):
|
|||||||
"""
|
"""
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_context(cls, context, tree_node):
|
def from_context(cls, context, tree_node):
|
||||||
|
def create(tree_node):
|
||||||
|
return cls(context.evaluator, parent_context=context, tree_node=tree_node)
|
||||||
|
|
||||||
from jedi.evaluate.context import AbstractInstanceContext
|
from jedi.evaluate.context import AbstractInstanceContext
|
||||||
|
|
||||||
|
overloaded_funcs = list(_find_overload_functions(context, tree_node))
|
||||||
|
|
||||||
while context.is_class() or isinstance(context, AbstractInstanceContext):
|
while context.is_class() or isinstance(context, AbstractInstanceContext):
|
||||||
context = context.parent_context
|
context = context.parent_context
|
||||||
|
|
||||||
return cls(context.evaluator, parent_context=context, tree_node=tree_node)
|
function = create(tree_node)
|
||||||
|
|
||||||
|
if len(overloaded_funcs) > 1:
|
||||||
|
return OverloadedFunctionContext(
|
||||||
|
function,
|
||||||
|
ContextSet.from_iterable(create(f) for f in overloaded_funcs)
|
||||||
|
)
|
||||||
|
return function
|
||||||
|
|
||||||
def get_function_execution(self, arguments=None):
|
def get_function_execution(self, arguments=None):
|
||||||
if arguments is None:
|
if arguments is None:
|
||||||
@@ -255,3 +267,76 @@ class FunctionExecutionContext(TreeContext):
|
|||||||
@evaluator_method_cache()
|
@evaluator_method_cache()
|
||||||
def get_executed_params(self):
|
def get_executed_params(self):
|
||||||
return self.var_args.get_executed_params(self)
|
return self.var_args.get_executed_params(self)
|
||||||
|
|
||||||
|
|
||||||
|
class OverloadedFunctionContext(object):
|
||||||
|
def __init__(self, function, overloaded_functions):
|
||||||
|
self._function = function
|
||||||
|
self._overloaded_functions = overloaded_functions
|
||||||
|
|
||||||
|
def py__call__(self, arguments):
|
||||||
|
return ContextSet.from_sets(
|
||||||
|
f.py__call__(arguments=arguments)
|
||||||
|
for f in self._overloaded_functions
|
||||||
|
if signature_matches(f, arguments)
|
||||||
|
)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(self._function, name)
|
||||||
|
|
||||||
|
|
||||||
|
def signature_matches(function_context, arguments):
|
||||||
|
unpacked_arguments = arguments.unpack()
|
||||||
|
for param_node in function_context.tree_node.get_params():
|
||||||
|
key, argument = next(unpacked_arguments, (None, None))
|
||||||
|
print(param_node)
|
||||||
|
if argument is None:
|
||||||
|
# This signature has an parameter more than arguments were given.
|
||||||
|
return False
|
||||||
|
if key is not None:
|
||||||
|
# TODO this is obviously wrong, we cannot just ignore keyword
|
||||||
|
# arguments, but it's easier for now.
|
||||||
|
return False
|
||||||
|
|
||||||
|
if param_node.annotation is not None:
|
||||||
|
annotation_result = function_context.evaluator.eval_node(
|
||||||
|
function_context.parent_context,
|
||||||
|
param_node.annotation
|
||||||
|
)
|
||||||
|
print(annotation_result)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _find_overload_functions(context, tree_node):
|
||||||
|
def _is_overload_decorated(funcdef):
|
||||||
|
if funcdef.parent.type == 'decorated':
|
||||||
|
decorators = funcdef.parent.children[0]
|
||||||
|
if decorators.type == 'decorator':
|
||||||
|
decorators = [decorators]
|
||||||
|
else:
|
||||||
|
decorators = decorators.children
|
||||||
|
for decorator in decorators:
|
||||||
|
dotted_name = decorator.children[1]
|
||||||
|
if dotted_name.type == 'name' and dotted_name.value == 'overload':
|
||||||
|
# TODO check with contexts if it's the right overload
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
if _is_overload_decorated(tree_node):
|
||||||
|
yield tree_node
|
||||||
|
|
||||||
|
while True:
|
||||||
|
filter = ParserTreeFilter(
|
||||||
|
context.evaluator,
|
||||||
|
context,
|
||||||
|
until_position=tree_node.start_pos
|
||||||
|
)
|
||||||
|
names = filter.get(tree_node.name.value)
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
funcdef = name.tree_name.parent
|
||||||
|
if funcdef.type == 'funcdef' and _is_overload_decorated(funcdef):
|
||||||
|
yield funcdef
|
||||||
|
|
||||||
|
break # By default break
|
||||||
|
|||||||
@@ -296,6 +296,7 @@ class TypeVar(Context):
|
|||||||
def execute_annotation(self):
|
def execute_annotation(self):
|
||||||
if self._bound_lazy_context is not None:
|
if self._bound_lazy_context is not None:
|
||||||
return self._bound_lazy_context.infer().execute_annotation()
|
return self._bound_lazy_context.infer().execute_annotation()
|
||||||
|
debug.warning('Tried to infer a TypeVar without a given type')
|
||||||
return NO_CONTEXTS
|
return NO_CONTEXTS
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@@ -305,5 +306,5 @@ class TypeVar(Context):
|
|||||||
class OverloadFunction(_BaseTypingContext):
|
class OverloadFunction(_BaseTypingContext):
|
||||||
@repack_with_argument_clinic('func, /')
|
@repack_with_argument_clinic('func, /')
|
||||||
def py__call__(self, func_context_set):
|
def py__call__(self, func_context_set):
|
||||||
debug.warning('overload used %s', func_context_set)
|
# Just pass arguments through.
|
||||||
return func_context_set
|
return func_context_set
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ from jedi.cache import memoize_method
|
|||||||
from jedi.evaluate.base_context import ContextSet, iterator_to_context_set
|
from jedi.evaluate.base_context import ContextSet, iterator_to_context_set
|
||||||
from jedi.evaluate.filters import AbstractTreeName, ParserTreeFilter, \
|
from jedi.evaluate.filters import AbstractTreeName, ParserTreeFilter, \
|
||||||
TreeNameDefinition
|
TreeNameDefinition
|
||||||
from jedi.evaluate.context import ModuleContext, FunctionContext, ClassContext
|
from jedi.evaluate.context import ModuleContext, FunctionContext, \
|
||||||
|
ClassContext, BoundMethod
|
||||||
from jedi.evaluate.context.typing import TypingModuleFilterWrapper, \
|
from jedi.evaluate.context.typing import TypingModuleFilterWrapper, \
|
||||||
TypingModuleName
|
TypingModuleName
|
||||||
from jedi.evaluate.compiled import CompiledObject
|
from jedi.evaluate.compiled import CompiledObject
|
||||||
|
|||||||
Reference in New Issue
Block a user