Exemplo n.º 1
0
    def parse_class_by_jedi_name(self, jedi_name: Name) -> ParsedClass:
        """
        To parse a class definition by its Jedi Name.

        Args:
            jedi_name: the Jedi Name of the target class to parse

        Returns:
            The parsed class in ParsedClass
        """
        # case of being the object class
        if jedi_name.full_name == 'builtins.object':
            return PARSED_OBJECT_CLASS
        # case of a class not defined by a recognised script, so external class
        if not jedi_name.module_path:
            return ParsedPackageClass(jedi_name)
        # case of a custom class definition, which should have a dot-separate
        # full name starting with the full name of the module/script, and its
        # type should be `class`. There is case that the first condition is
        # satisfied but the second not, like a type alias definition/assignment
        # has a type `statement`.
        # use `class_name.goto()[0]` to fetch the full content Jedi Name which
        # has the `full_name` field
        if jedi_name.goto()[0].full_name.startswith(
                jedi_name.module_name) and jedi_name.type == 'class':
            return ParsedCustomClass(jedi_name, self)
        else:
            return ParsedPackageClass(jedi_name)
Exemplo n.º 2
0
        def definition(correct, correct_start, path):
            should_be = set()
            for match in re.finditer('(?:[^ ]+)', correct):
                string = match.group(0)
                parser = grammar36.parse(string,
                                         start_symbol='eval_input',
                                         error_recovery=False)
                parser_utils.move(parser.get_root_node(), self.line_nr)
                node = parser.get_root_node()
                module_context = script._get_module_context()
                user_context = get_user_context(module_context,
                                                (self.line_nr, 0))
                node.parent = user_context.tree_node
                results = convert_values(user_context.infer_node(node))
                if not results:
                    raise Exception('Could not resolve %s on line %s' %
                                    (match.string, self.line_nr - 1))

                should_be |= set(
                    Name(inference_state, r.name) for r in results)
            debug.dbg('Finished getting types', color='YELLOW')

            # Because the objects have different ids, `repr`, then compare.
            should = set(comparison(r) for r in should_be)
            return should
Exemplo n.º 3
0
def lsp_symbol_information(name: Name) -> SymbolInformation:
    """Get LSP SymbolInformation from Jedi definition."""
    return SymbolInformation(
        name=name.name,
        kind=get_lsp_symbol_type(name.type),
        location=lsp_location(name),
        container_name=name.parent(),
    )
Exemplo n.º 4
0
def _document_symbol_range(name: Name) -> Range:
    """Get accurate full range of function.

    Thanks <https://github.com/CXuesong> from
    <https://github.com/palantir/python-language-server/pull/537/files> for the
    inspiration!

    Note: I add tons of extra space to make dictionary completions work. Jedi
    cuts off the end sometimes before the final function statement. This may be
    the cause of bugs at some point.
    """
    start = name.get_definition_start_position()
    end = name.get_definition_end_position()
    if start is None or end is None:
        return lsp_range(name)
    (start_line, start_column) = start
    (end_line, end_column) = end
    return Range(
        start=Position(line=start_line - 1, character=start_column),
        end=Position(line=end_line - 1, character=end_column),
    )
Exemplo n.º 5
0
    def build_documentation(name: JediName) -> str:
        LOGGER.debug(f"name: {repr(name)}")
        try:
            module_name = name.module_name
            module_path = name.module_path
            type_ = name.type
            signature = (name._get_docstring_signature()
                         if type_ in {"class", "function"} else "")
            docstring = name._get_docstring()
        except Exception as err:
            LOGGER.debug(err)
            return ""

        # header
        header = (f"module: <code>{module_name}</code>"
                  if module_name and module_name != "__main__" else "")
        # title
        title = f"<h3>{type_} <strong><code>{name.name}</code></strong></h3>"
        # signature
        signature = (f"<p><code>{escape_characters(signature)}</code></p>"
                     if signature else "")
        # body
        body = f"<p>{escape_characters(docstring)}</p>" if docstring else ""

        # footer
        footer = ""
        try:
            row, col = name.line, name.column
            # use one-based column index
            col += 1
            module_path = (module_path if module_path
                           and module_path != "__main__" else "")
            footer = f"<a href='{module_path}:{row}:{col}'>Go to definition</a>"
        except Exception as err:
            LOGGER.debug(err)

        result = "\n".join([
            item for item in (header, title, signature, body, footer) if item
        ])
        return f"<div>{result}</div>"
Exemplo n.º 6
0
def _docstring_markdown(name: Name) -> str:
    doc = name.docstring()
    if not doc:
        return ''
    if name.type in ['class', 'function']:
        try:
            sig, doc = doc.split('\n\n', 1)
        except ValueError:
            sig = doc
            doc = False
        sig = f'```python\n{sig}\n```'
        if doc:
            return f'{sig}\n\n```\n{doc}\n```'
        return sig
    return f'```\n{doc}\n```'
Exemplo n.º 7
0
    def _is_original_class(class_name: Name, script_context: Name) -> bool:
        """
        To check if a jedi Name is an originally defined class in a script.

        Args:
            class_name: the Name of the target class
            script_context: the context of the target script

        Returns:
            `True` if the class is an originally defined class or `False`
            otherwise
        """
        if not script_context.module_name:
            return class_name.type == 'class'
        # use `class_name.goto()[0]` to fetch the full content Jedi Name which
        # has the `full_name` field
        return class_name.type == 'class' and \
            class_name.goto()[0].full_name.startswith(
                script_context.module_name
            )
Exemplo n.º 8
0
def _docstring(name: Name) -> str:
    return name.docstring()