Ejemplo n.º 1
0
Archivo: api.py Proyecto: rayleyva/jedi
    def call_signatures(self):
        """
        Return the function object of the call you're currently in.

        E.g. if the cursor is here::

            abs(# <-- cursor is here

        This would return the ``abs`` function. On the other hand::

            abs()# <-- cursor is here

        This would return ``None``.

        :rtype: list of :class:`api_classes.CallDef`
        """

        call, index = self._func_call_and_param_index()
        if call is None:
            return []

        user_stmt = self._user_stmt()
        with common.scale_speed_settings(settings.scale_call_signatures):
            _callable = lambda: evaluate.follow_call(call)
            origins = cache.cache_call_signatures(_callable, user_stmt)
        debug.speed('func_call followed')

        return [
            api_classes.CallDef(o, index, call) for o in origins
            if o.isinstance(er.Function, er.Instance, er.Class)
        ]
Ejemplo n.º 2
0
    def function_definition(self):
        """
        Return the function object of the call you're currently in.

        E.g. if the cursor is here::

            abs(# <-- cursor is here

        This would return the ``abs`` function. On the other hand::

            abs()# <-- cursor is here

        This would return ``None``.

        :rtype: :class:`api_classes.CallDef`
        """

        (call, index) = self._func_call_and_param_index()
        if call is None:
            return None

        user_stmt = self._parser.user_stmt
        with common.scale_speed_settings(settings.scale_function_definition):
            _callable = lambda: evaluate.follow_call(call)
            origins = cache.cache_function_definition(_callable, user_stmt)
        debug.speed('func_call followed')

        if len(origins) == 0:
            return None
        # just take entry zero, because we need just one.
        executable = origins[0]

        return api_classes.CallDef(executable, index, call)
Ejemplo n.º 3
0
Archivo: dynamic.py Proyecto: 1st1/jedi
def check_statement_information(stmt, search_name):
    try:
        ass = stmt.get_assignment_calls()
        try:
            call = ass.get_only_subelement()
        except AttributeError:
            assert False
        assert type(call) == parsing.Call and str(call.name) == 'isinstance'
        assert bool(call.execution)

        # isinstance check
        isinst = call.execution.values
        assert len(isinst) == 2  # has two params
        assert len(isinst[0]) == 1
        assert len(isinst[1]) == 1
        assert isinstance(isinst[0][0], parsing.Call)
        # names fit?
        assert str(isinst[0][0].name) == search_name
        classes_call = isinst[1][0]  # class_or_type_or_tuple
        assert isinstance(classes_call, parsing.Call)
        result = []
        for c in evaluate.follow_call(classes_call):
            if isinstance(c, evaluate.Array):
                result += c.get_index_types()
            else:
                result.append(c)
        for i, c in enumerate(result):
            result[i] = evaluate.Instance(c)
        return result
    except AssertionError:
        return []
Ejemplo n.º 4
0
    def call_signatures(self):
        """
        Return the function object of the call you're currently in.

        E.g. if the cursor is here::

            abs(# <-- cursor is here

        This would return the ``abs`` function. On the other hand::

            abs()# <-- cursor is here

        This would return ``None``.

        :rtype: list of :class:`api_classes.CallDef`
        """

        call, index = self._func_call_and_param_index()
        if call is None:
            return []

        user_stmt = self._user_stmt()
        with common.scale_speed_settings(settings.scale_call_signatures):
            _callable = lambda: evaluate.follow_call(call)
            origins = cache.cache_call_signatures(_callable, user_stmt)
        debug.speed('func_call followed')

        return [api_classes.CallDef(o, index, call) for o in origins
                if o.isinstance(er.Function, er.Instance, er.Class)]
Ejemplo n.º 5
0
def _check_isinstance_type(stmt, search_name):
    try:
        commands = stmt.get_commands()
        # this might be removed if we analyze and, etc
        assert len(commands) == 1
        call = commands[0]
        assert type(call) is pr.Call and str(call.name) == "isinstance"
        assert bool(call.execution)

        # isinstance check
        isinst = call.execution.values
        assert len(isinst) == 2  # has two params
        obj, classes = [statement.get_commands() for statement in isinst]
        assert len(obj) == 1
        assert len(classes) == 1
        assert isinstance(obj[0], pr.Call)
        # names fit?
        assert str(obj[0].name) == search_name
        assert isinstance(classes[0], pr.Call)  # can be type or tuple
    except AssertionError:
        return []

    result = []
    for c in evaluate.follow_call(classes[0]):
        if isinstance(c, er.Array):
            result += c.get_index_types()
        else:
            result.append(c)
    for i, c in enumerate(result):
        result[i] = er.Instance(c)
    return result
Ejemplo n.º 6
0
def check_statement_information(stmt, search_name):
    try:
        ass = stmt.get_assignment_calls()
        try:
            call = ass.get_only_subelement()
        except AttributeError:
            assert False
        assert type(call) == parsing.Call and str(call.name) == 'isinstance'
        assert bool(call.execution)

        # isinstance check
        isinst = call.execution.values
        assert len(isinst) == 2  # has two params
        assert len(isinst[0]) == 1
        assert len(isinst[1]) == 1
        assert isinstance(isinst[0][0], parsing.Call)
        # names fit?
        assert str(isinst[0][0].name) == search_name
        classes_call = isinst[1][0]  # class_or_type_or_tuple
        assert isinstance(classes_call, parsing.Call)
        result = []
        for c in evaluate.follow_call(classes_call):
            if isinstance(c, evaluate.Array):
                result += c.get_index_types()
            else:
                result.append(c)
        for i, c in enumerate(result):
            result[i] = evaluate.Instance(c)
        return result
    except AssertionError:
        return []
Ejemplo n.º 7
0
def check_statement_information(stmt, search_name):
    try:
        commands = stmt.get_commands()
        # this might be removed if we analyze and, etc
        assert len(commands) == 1
        call = commands[0]
        assert type(call) == pr.Call and str(call.name) == 'isinstance'
        assert bool(call.execution)

        # isinstance check
        isinst = call.execution.values
        assert len(isinst) == 2  # has two params
        obj, classes = [statement.get_commands() for statement in isinst]
        assert len(obj) == 1
        assert len(classes) == 1
        assert isinstance(obj[0], pr.Call)
        # names fit?
        assert str(obj[0].name) == search_name
        assert isinstance(classes[0], pr.Call)  # can be type or tuple
    except AssertionError:
        return []

    result = []
    for c in evaluate.follow_call(classes[0]):
        if isinstance(c, er.Array):
            result += c.get_index_types()
        else:
            result.append(c)
    for i, c in enumerate(result):
        result[i] = er.Instance(c)
    return result
Ejemplo n.º 8
0
Archivo: api.py Proyecto: omab/dotfiles
    def get_in_function_call(self):
        """
        Return the function, that the cursor is in, e.g.:
        >>> isinstance(| # | <-- cursor is here

        This would return the `isinstance` function. In contrary:
        >>> isinstance()| # | <-- cursor is here

        This would return `None`.
        """
        def check_user_stmt(user_stmt):
            if user_stmt is None \
                        or not isinstance(user_stmt, parsing.Statement):
                return None, 0
            ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls())

            call, index, stop = helpers.scan_array_for_pos(ass, self.pos)
            return call, index

        def check_cache():
            """ Do the parsing with a part parser, therefore reduce ressource
            costs.
            TODO this is not working with multi-line docstrings, improve.
            """
            if self.source_path is None:
                return None, 0

            try:
                timestamp, parser = builtin.CachedModule.cache[
                                                            self.source_path]
            except KeyError:
                return None, 0
            part_parser = self.module.get_part_parser()
            user_stmt = part_parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call:
                old_stmt = parser.module.get_statement_for_position(self.pos)
                if old_stmt is None:
                    return None, 0
                old_call, old_index = check_user_stmt(old_stmt)
                if old_call:
                    # compare repr because that should definitely be the same.
                    # Otherwise the whole thing is out of sync.
                    if repr(old_call) == repr(call):
                        # return the index of the part_parser
                        return old_call, index
                return None, 0
            else:
                raise NotFoundError()

        debug.speed('func_call start')
        try:
            call, index = check_cache()
        except NotFoundError:
            return None
        debug.speed('func_call parsed')

        if call is None:
            # This is a backup, if the above is not successful.
            user_stmt = self.parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call is None:
                return None

        debug.speed('func_call user_stmt')
        with common.scale_speed_settings(settings.scale_get_in_function_call):
            origins = evaluate.follow_call(call)
        debug.speed('func_call followed')

        if len(origins) == 0:
            return None
        # just take entry zero, because we need just one.
        executable = origins[0]

        return api_classes.CallDef(executable, index, call)
Ejemplo n.º 9
0
    def get_in_function_call(self):
        """
        Return the function, that the cursor is in, e.g.:
        >>> isinstance(| # | <-- cursor is here

        This would return the `isinstance` function. In contrary:
        >>> isinstance()| # | <-- cursor is here

        This would return `None`.
        """
        def scan_array_for_pos(arr, pos):
            """
            Returns the function Call that match search_name in an Array.
            """
            index = 0
            call = None
            stop = False
            for index, sub in enumerate(arr.values):
                call = None
                for s in sub:
                    if isinstance(s, parsing.Array):
                        new = scan_array_for_pos(s, pos)
                        if new[0] is not None:
                            call, index, stop = new
                            if stop:
                                return call, index, stop
                    elif isinstance(s, parsing.Call):
                        start_s = s
                        while s is not None:
                            if s.start_pos >= pos:
                                return call, index, stop
                            elif s.execution is not None:
                                end = s.execution.end_pos
                                if s.execution.start_pos < pos and \
                                        (end is None or pos < end):
                                    c, index, stop = scan_array_for_pos(
                                                            s.execution, pos)
                                    if stop:
                                        return c, index, stop

                                    # call should return without execution and
                                    # next
                                    reset = c or s
                                    if reset.execution.type not in \
                                                [parsing.Array.TUPLE,
                                                parsing.Array.NOARRAY]:
                                        return start_s, index, False

                                    reset.execution = None
                                    reset.next = None
                                    return c or start_s, index, True
                            s = s.next

            # The third return is just necessary for recursion inside, because
            # it needs to know when to stop iterating.
            return call, index, stop

        user_stmt = self.parser.user_stmt
        if user_stmt is None or not isinstance(user_stmt, parsing.Statement):
            return None
        ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls())

        call, index, stop = scan_array_for_pos(ass, self.pos)
        if call is None:
            return None

        origins = evaluate.follow_call(call)

        if len(origins) == 0:
            return None
        # just take entry zero, because we need just one.
        executable = origins[0]

        after = self.module.get_line(self.pos[0])[self.pos[1]:]
        index -= re.search('^[ ,]*', after).group(0).count(',')
        return CallDef(executable, index, call)
Ejemplo n.º 10
0
    def get_in_function_call(self):
        """
        Return the function, that the cursor is in, e.g.:
        >>> isinstance(| # | <-- cursor is here

        This would return the `isinstance` function. In contrary:
        >>> isinstance()| # | <-- cursor is here

        This would return `None`.
        """
        def check_user_stmt(user_stmt):
            if user_stmt is None \
                        or not isinstance(user_stmt, parsing.Statement):
                return None, 0
            ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls())

            call, index, stop = helpers.scan_array_for_pos(ass, self.pos)
            return call, index

        def check_cache():
            """ Do the parsing with a part parser, therefore reduce ressource
            costs.
            TODO this is not working with multi-line docstrings, improve.
            """
            if self.source_path is None:
                return None, 0

            try:
                timestamp, parser = builtin.CachedModule.cache[
                    self.source_path]
            except KeyError:
                return None, 0
            part_parser = self.module.get_part_parser()
            user_stmt = part_parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call:
                old_stmt = parser.module.get_statement_for_position(self.pos)
                if old_stmt is None:
                    return None, 0
                old_call, old_index = check_user_stmt(old_stmt)
                if old_call:
                    # compare repr because that should definitely be the same.
                    # Otherwise the whole thing is out of sync.
                    if repr(old_call) == repr(call):
                        # return the index of the part_parser
                        return old_call, index
                return None, 0
            else:
                raise NotFoundError()

        debug.speed('func_call start')
        try:
            call, index = check_cache()
        except NotFoundError:
            return None
        debug.speed('func_call parsed')

        if call is None:
            # This is a backup, if the above is not successful.
            user_stmt = self.parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call is None:
                return None

        debug.speed('func_call user_stmt')
        with helpers.scale_speed_settings(settings.scale_get_in_function_call):
            origins = evaluate.follow_call(call)
        debug.speed('func_call followed')

        if len(origins) == 0:
            return None
        # just take entry zero, because we need just one.
        executable = origins[0]

        return api_classes.CallDef(executable, index, call)
Ejemplo n.º 11
0
    def get_in_function_call(self):
        """
        Return the function object of the call you're currently in.

        E.g. if the cursor is here::

            >>> abs(# <-- cursor is here

        This would return the ``abs`` function. On the other hand::

            >>> abs()# <-- cursor is here

        This would return ``None``.

        :rtype: :class:`api_classes.CallDef`
        """
        def check_user_stmt(user_stmt):
            if user_stmt is None \
                        or not isinstance(user_stmt, parsing.Statement):
                return None, 0
            ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls())

            call, index, stop = helpers.search_function_call(ass, self.pos)
            return call, index

        def check_cache():
            """ Do the parsing with a part parser, therefore reduce ressource
            costs.
            TODO this is not working with multi-line docstrings, improve.
            """
            if self.source_path is None:
                return None, 0

            try:
                parser = cache.parser_cache[self.source_path].parser
            except KeyError:
                return None, 0
            part_parser = self._module.get_part_parser()
            user_stmt = part_parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call:
                old_stmt = parser.module.get_statement_for_position(self.pos)
                if old_stmt is None:
                    return None, 0
                old_call, old_index = check_user_stmt(old_stmt)
                if old_call:
                    # compare repr because that should definitely be the same.
                    # Otherwise the whole thing is out of sync.
                    if repr(old_call) == repr(call):
                        # return the index of the part_parser
                        return old_call, index
                return None, 0
            else:
                raise NotFoundError()

        debug.speed('func_call start')
        call = None
        if settings.use_get_in_function_call_cache:
            try:
                call, index = check_cache()
            except NotFoundError:
                return None

        user_stmt = self._parser.user_stmt
        if call is None:
            # This is a backup, if the above is not successful.
            call, index = check_user_stmt(user_stmt)
            if call is None:
                return None
        debug.speed('func_call parsed')

        with common.scale_speed_settings(settings.scale_get_in_function_call):
            _callable = lambda: evaluate.follow_call(call)
            origins = cache.cache_get_in_function_call(_callable, user_stmt)
        debug.speed('func_call followed')

        if len(origins) == 0:
            return None
        # just take entry zero, because we need just one.
        executable = origins[0]

        return api_classes.CallDef(executable, index, call)