2
2
DocumentationComment )
3
3
from coalib .bearlib .languages .documentation .DocstyleDefinition import (
4
4
DocstyleDefinition )
5
- from coalib .bearlib .languages .documentation .DocumentationExtraction import (
6
- extract_documentation )
5
+ from coalib .bearlib .languages .documentation .DocBaseClass import (
6
+ DocBaseClass )
7
7
from coalib .bears .LocalBear import LocalBear
8
- from coalib .results .Diff import Diff
9
8
from coalib .results .Result import Result
10
- from coalib .results .TextRange import TextRange
11
9
10
+ from textwrap import dedent
12
11
13
- class DocumentationStyleBear (LocalBear ):
12
+
13
+ class DocumentationStyleBear (DocBaseClass , LocalBear ):
14
14
LANGUAGES = {language for docstyle , language in
15
15
DocstyleDefinition .get_available_definitions ()}
16
16
AUTHORS = {'The coala developers' }
@@ -20,6 +20,71 @@ class DocumentationStyleBear(LocalBear):
20
20
CAN_DETECT = {'Documentation' }
21
21
CAN_FIX = {'Documentation' }
22
22
23
+ def process_documentation (self , parsed , allow_missing_func_desc : str = False ,
24
+ indent_size : int = 4 ):
25
+ """
26
+ This fixes the parsed documentation comment.
27
+
28
+ :param parsed:
29
+ Contains parsed documentation comment.
30
+ :param allow_missing_func_desc:
31
+ When set ``True`` this will allow functions with missing
32
+ descriptions, allowing functions to start with params.
33
+ :param indent_size:
34
+ Number of spaces per indentation level.
35
+ :return:
36
+ A tuple of fixed parsed documentation comment and warning_desc.
37
+ """
38
+ # Assuming that the first element is always the only main
39
+ # description.
40
+ metadata = iter (parsed )
41
+
42
+ main_description = next (metadata )
43
+
44
+ if main_description .desc == '\n ' and not allow_missing_func_desc :
45
+ # Triple quoted string literals doesn't look good. It breaks
46
+ # the line of flow. Hence we use dedent.
47
+ warning_desc = dedent ("""\
48
+ Missing function description.
49
+ Please set allow_missing_func_desc = True to ignore this warning.
50
+ """ )
51
+ else :
52
+ warning_desc = 'Documentation does not have correct style.'
53
+
54
+ # one empty line shall follow main description (except it's empty
55
+ # or no annotations follow).
56
+ if main_description .desc .strip () != '' :
57
+ main_description = main_description ._replace (
58
+ desc = '\n ' + main_description .desc .strip () + '\n ' *
59
+ (1 if len (parsed ) == 1 else 2 ))
60
+
61
+ new_metadata = [main_description ]
62
+ for m in metadata :
63
+ # Split newlines and remove leading and trailing whitespaces.
64
+ stripped_desc = list (map (str .strip , m .desc .splitlines ()))
65
+ if len (stripped_desc ) == 0 :
66
+ # Annotations should be on their own line, though no
67
+ # further description follows.
68
+ stripped_desc .append ('' )
69
+ else :
70
+ # Wrap parameter description onto next line if it follows
71
+ # annotation directly.
72
+ if stripped_desc [0 ] != '' :
73
+ stripped_desc .insert (0 , '' )
74
+
75
+ # Indent with 4 spaces.
76
+ stripped_desc = ('' if line == '' else ' ' * indent_size
77
+ + line for line in stripped_desc )
78
+
79
+ new_desc = '\n ' .join (stripped_desc )
80
+
81
+ # Strip away trailing whitespaces and obsolete newlines (except
82
+ # one newline which is mandatory).
83
+ new_desc = new_desc .rstrip () + '\n '
84
+
85
+ new_metadata .append (m ._replace (desc = new_desc .lstrip (' ' )))
86
+ return (new_metadata , warning_desc )
87
+
23
88
def run (self , filename , file , language : str ,
24
89
docstyle : str = 'default' , allow_missing_func_desc : str = False ,
25
90
indent_size : int = 4 ):
@@ -46,72 +111,20 @@ def run(self, filename, file, language: str,
46
111
functions to start with params.
47
112
:param indent_size: Number of spaces per indentation level.
48
113
"""
49
- for doc_comment in extract_documentation (file , language , docstyle ):
50
- parsed = doc_comment .parse ()
51
- metadata = iter (parsed )
52
114
53
- # Assuming that the first element is always the only main
54
- # description.
55
- main_description = next (metadata )
115
+ for doc_comment in self .extract (file , language , docstyle ):
116
+ parsed = doc_comment .parse ()
56
117
57
- if main_description .desc == '\n ' and not allow_missing_func_desc :
58
- warning_desc = """
59
- Missing function description.
60
- Please set allow_missing_func_desc = True to ignore this warning.
61
- """
62
- else :
63
- warning_desc = 'Documentation does not have correct style.'
64
-
65
- # one empty line shall follow main description (except it's empty
66
- # or no annotations follow).
67
- if main_description .desc .strip () != '' :
68
- main_description = main_description ._replace (
69
- desc = '\n ' + main_description .desc .strip () + '\n ' *
70
- (1 if len (parsed ) == 1 else 2 ))
71
-
72
- new_metadata = [main_description ]
73
- for m in metadata :
74
- # Split newlines and remove leading and trailing whitespaces.
75
- stripped_desc = list (map (str .strip , m .desc .splitlines ()))
76
-
77
- if len (stripped_desc ) == 0 :
78
- # Annotations should be on their own line, though no
79
- # further description follows.
80
- stripped_desc .append ('' )
81
- else :
82
- # Wrap parameter description onto next line if it follows
83
- # annotation directly.
84
- if stripped_desc [0 ] != '' :
85
- stripped_desc .insert (0 , '' )
86
-
87
- # Indent with 4 spaces.
88
- stripped_desc = ('' if line == '' else ' ' * indent_size
89
- + line for line in stripped_desc )
90
-
91
- new_desc = '\n ' .join (stripped_desc )
92
-
93
- # Strip away trailing whitespaces and obsolete newlines (except
94
- # one newline which is mandatory).
95
- new_desc = new_desc .rstrip () + '\n '
96
-
97
- new_metadata .append (m ._replace (desc = new_desc .lstrip (' ' )))
118
+ (new_metadata , warning_desc ) = self .process_documentation (
119
+ parsed , allow_missing_func_desc , indent_size )
98
120
99
121
new_comment = DocumentationComment .from_metadata (
100
122
new_metadata , doc_comment .docstyle_definition ,
101
123
doc_comment .marker , doc_comment .indent , doc_comment .position )
102
124
103
125
if new_comment != doc_comment :
104
126
# Something changed, let's apply a result.
105
- diff = Diff (file )
106
-
107
- # We need to update old comment positions, as `assemble()`
108
- # prepends indentation for first line.
109
- old_range = TextRange .from_values (
110
- doc_comment .range .start .line ,
111
- 1 ,
112
- doc_comment .range .end .line ,
113
- doc_comment .range .end .column )
114
- diff .replace (old_range , new_comment .assemble ())
127
+ diff = self .generate_diff (file , doc_comment , new_comment )
115
128
116
129
yield Result (
117
130
origin = self ,
0 commit comments