]> git.lizzy.rs Git - rust.git/blob - src/etc/sugarise-doc-comments.py
Auto merge of #29325 - alexcrichton:revert-trait-accessibility, r=nrc
[rust.git] / src / etc / sugarise-doc-comments.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
4 # file at the top-level directory of this distribution and at
5 # http://rust-lang.org/COPYRIGHT.
6 #
7 # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8 # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9 # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10 # option. This file may not be copied, modified, or distributed
11 # except according to those terms.
12
13 #
14 # this script attempts to turn doc comment attributes (#[doc = "..."])
15 # into sugared-doc-comments (/** ... */ and /// ...)
16 #
17 # it sugarises all .rs/.rc files underneath the working directory
18 #
19
20 import sys
21 import os
22 import fnmatch
23 import re
24
25
26 DOC_PATTERN = '^(?P<indent>[\\t ]*)#\\[(\\s*)doc(\\s*)=' + \
27               '(\\s*)"(?P<text>(\\"|[^"])*?)"(\\s*)\\]' + \
28               '(?P<semi>;)?'
29
30 ESCAPES = [("\\'", "'"),
31            ('\\"', '"'),
32            ("\\n", "\n"),
33            ("\\r", "\r"),
34            ("\\t", "\t")]
35
36
37 def unescape(s):
38     for (find, repl) in ESCAPES:
39         s = s.replace(find, repl)
40     return s
41
42
43 def block_trim(s):
44     lns = s.splitlines()
45
46     # remove leading/trailing whitespace-lines
47     while lns and not lns[0].strip():
48         lns = lns[1:]
49     while lns and not lns[-1].strip():
50         lns = lns[:-1]
51
52     # remove leading horizontal whitespace
53     n = sys.maxint
54     for ln in lns:
55         if ln.strip():
56             n = min(n, len(re.search('^\s*', ln).group()))
57     if n != sys.maxint:
58         lns = [ln[n:] for ln in lns]
59
60     # strip trailing whitespace
61     lns = [ln.rstrip() for ln in lns]
62
63     return lns
64
65
66 def replace_doc(m):
67     indent = m.group('indent')
68     text = block_trim(unescape(m.group('text')))
69
70     if len(text) > 1:
71         inner = '!' if m.group('semi') else '*'
72         starify = lambda s: indent + ' *' + (' ' + s if s else '')
73         text = '\n'.join(map(starify, text))
74         repl = indent + '/*' + inner + '\n' + text + '\n' + indent + ' */'
75     else:
76         inner = '!' if m.group('semi') else '/'
77         repl = indent + '//' + inner + ' ' + text[0]
78
79     return repl
80
81
82 def sugarise_file(path):
83     s = open(path).read()
84
85     r = re.compile(DOC_PATTERN, re.MULTILINE | re.DOTALL)
86     ns = re.sub(r, replace_doc, s)
87
88     if s != ns:
89         open(path, 'w').write(ns)
90
91 for (dirpath, dirnames, filenames) in os.walk('.'):
92     for name in fnmatch.filter(filenames, '*.r[sc]'):
93         sugarise_file(os.path.join(dirpath, name))