Example #1
0
    def process_documentation(self,
                              doc_comment: DocumentationComment,
                              allow_missing_func_desc: str = False,
                              indent_size: int = 4,
                              expand_one_liners: str = False):
        """
        This fixes the parsed documentation comment.

        :param doc_comment:
            Contains instance of DocumentationComment.
        :param allow_missing_func_desc:
            When set ``True`` this will allow functions with missing
            descriptions, allowing functions to start with params.
        :param indent_size:
            Number of spaces per indentation level.
        :param expand_one_liners:
            When set ``True`` this will expand one liner docstrings.
        :return:
            A tuple of fixed parsed documentation comment and warning_desc.
        """
        parsed = doc_comment.parse()
        # Assuming that the first element is always the only main
        # description.
        metadata = iter(parsed)

        main_description = next(metadata)

        if main_description.desc == '\n' and not allow_missing_func_desc:
            # Triple quoted string literals doesn't look good. It breaks
            # the line of flow. Hence we use dedent.
            warning_desc = dedent("""\
            Missing function description.
            Please set allow_missing_func_desc = True to ignore this warning.
            """)
        else:
            warning_desc = 'Documentation does not have correct style.'

        # one empty line shall follow main description (except it's empty
        # or no annotations follow).
        if main_description.desc.strip() != '':
            if not expand_one_liners and len(parsed) == 1:
                main_description = main_description._replace(
                    desc=main_description.desc.strip())
            else:
                main_description = main_description._replace(
                    desc='\n' + main_description.desc.strip() + '\n' *
                    (1 if len(parsed) == 1 else 2))

        new_metadata = [main_description]
        for m in metadata:
            # Split newlines and remove leading and trailing whitespaces.
            stripped_desc = list(map(str.strip, m.desc.splitlines()))
            if len(stripped_desc) == 0:
                # Annotations should be on their own line, though no
                # further description follows.
                stripped_desc.append('')
            else:
                # Wrap parameter description onto next line if it follows
                # annotation directly.
                if stripped_desc[0] != '':
                    stripped_desc.insert(0, '')

            # Indent with 4 spaces.
            stripped_desc = ('' if line == '' else ' ' * indent_size + line
                             for line in stripped_desc)

            new_desc = '\n'.join(stripped_desc)

            # Strip away trailing whitespaces and obsolete newlines (except
            # one newline which is mandatory).
            new_desc = new_desc.rstrip() + '\n'

            new_metadata.append(m._replace(desc=new_desc.lstrip(' ')))

        new_comment = DocumentationComment.from_metadata(
            new_metadata, doc_comment.docstyle_definition, doc_comment.marker,
            doc_comment.indent, doc_comment.position)

        # Instantiate default padding.
        class_padding = doc_comment.docstyle_definition.class_padding
        function_padding = doc_comment.docstyle_definition.function_padding
        # Check if default padding exist in the coalang file.
        if (class_padding != DocstyleDefinition.ClassPadding('', '')
                and function_padding != DocstyleDefinition.FunctionPadding(
                    '', '')):
            # Check docstring_type
            if doc_comment.docstring_type == 'class':
                new_comment.top_padding = class_padding.top_padding
                new_comment.bottom_padding = class_padding.bottom_padding
            elif doc_comment.docstring_type == 'function':
                new_comment.top_padding = function_padding.top_padding
                new_comment.bottom_padding = function_padding.bottom_padding
            else:
                # Keep paddings as they are originally.
                new_comment.top_padding = doc_comment.top_padding
                new_comment.bottom_padding = doc_comment.bottom_padding
        else:
            # If there's no default paddings defined. Keep padding as
            # they are originally.
            new_comment.top_padding = doc_comment.top_padding
            new_comment.bottom_padding = doc_comment.bottom_padding

        return (new_comment, warning_desc)