Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: third_party/cython/src/Cython/Compiler/Annotate.py

Issue 385073004: Adding cython v0.20.2 in third-party. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reference cython dev list thread. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Note: Work in progress
2
3 import os
4 import re
5 import codecs
6 from xml.sax.saxutils import escape as html_escape
7 from StringIO import StringIO
8
9 import Version
10 from Code import CCodeWriter
11 from Cython import Utils
12
13 # need one-characters subsitutions (for now) so offsets aren't off
14 special_chars = [
15 (u'&', u'\xF2', u'&'),
16 (u'<', u'\xF0', u'&lt;'),
17 (u'>', u'\xF1', u'&gt;'),
18 ]
19
20
21 class AnnotationCCodeWriter(CCodeWriter):
22
23 def __init__(self, create_from=None, buffer=None, copy_formatting=True):
24 CCodeWriter.__init__(self, create_from, buffer, copy_formatting=True)
25 if create_from is None:
26 self.annotation_buffer = StringIO()
27 self.annotations = []
28 self.last_pos = None
29 self.code = {}
30 else:
31 # When creating an insertion point, keep references to the same data base
32 self.annotation_buffer = create_from.annotation_buffer
33 self.annotations = create_from.annotations
34 self.code = create_from.code
35 self.last_pos = create_from.last_pos
36
37 def create_new(self, create_from, buffer, copy_formatting):
38 return AnnotationCCodeWriter(create_from, buffer, copy_formatting)
39
40 def write(self, s):
41 CCodeWriter.write(self, s)
42 self.annotation_buffer.write(s)
43
44 def mark_pos(self, pos):
45 if pos is not None:
46 CCodeWriter.mark_pos(self, pos)
47 if self.last_pos:
48 pos_code = self.code.setdefault(self.last_pos[0].filename,{})
49 code = pos_code.get(self.last_pos[1], "")
50 pos_code[self.last_pos[1]] = code + self.annotation_buffer.getvalue( )
51 self.annotation_buffer = StringIO()
52 self.last_pos = pos
53
54 def annotate(self, pos, item):
55 self.annotations.append((pos, item))
56
57 def save_annotation(self, source_filename, target_filename):
58 self.mark_pos(None)
59 f = Utils.open_source_file(source_filename)
60 lines = f.readlines()
61 for k, line in enumerate(lines):
62 for c, cc, html in special_chars:
63 line = line.replace(c, cc)
64 lines[k] = line
65 f.close()
66 all = []
67 if False:
68 for pos, item in self.annotations:
69 if pos[0].filename == source_filename:
70 start = item.start()
71 size, end = item.end()
72 if size:
73 all.append((pos, start))
74 all.append(((source_filename, pos[1], pos[2]+size), end) )
75 else:
76 all.append((pos, start+end))
77
78 all.sort(reverse=True)
79 for pos, item in all:
80 _, line_no, col = pos
81 line_no -= 1
82 col += 1
83 line = lines[line_no]
84 lines[line_no] = line[:col] + item + line[col:]
85
86 html_filename = os.path.splitext(target_filename)[0] + ".html"
87 f = codecs.open(html_filename, "w", encoding="UTF-8")
88 f.write(u'<!DOCTYPE html>\n')
89 f.write(u'<!-- Generated by Cython %s -->\n' % Version.watermark)
90 f.write(u'<html>\n')
91 f.write(u"""
92 <head>
93 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
94 <style type="text/css">
95
96 body { font-family: courier; font-size: 12; }
97
98 .code { font-size: 9; color: #444444; display: none; margin-left: 20px; }
99 .py_c_api { color: red; }
100 .py_macro_api { color: #FF7000; }
101 .pyx_c_api { color: #FF3000; }
102 .pyx_macro_api { color: #FF7000; }
103 .refnanny { color: #FFA000; }
104
105 .error_goto { color: #FFA000; }
106
107 .tag { }
108
109 .coerce { color: #008000; border: 1px dotted #008000 }
110
111 .py_attr { color: #FF0000; font-weight: bold; }
112 .c_attr { color: #0000FF; }
113
114 .py_call { color: #FF0000; font-weight: bold; }
115 .c_call { color: #0000FF; }
116
117 .line { margin: 0em }
118
119 </style>
120 <script>
121 function toggleDiv(id) {
122 theDiv = document.getElementById(id);
123 if (theDiv.style.display != 'block') theDiv.style.display = 'block';
124 else theDiv.style.display = 'none';
125 }
126 </script>
127 </head>
128 """)
129 f.write(u'<body>\n')
130 f.write(u'<p>Generated by Cython %s\n' % Version.watermark)
131 c_file = Utils.decode_filename(os.path.basename(target_filename))
132 f.write(u'<p>Raw output: <a href="%s">%s</a>\n' % (c_file, c_file))
133
134 zero_calls = dict((name, 0) for name in
135 'refnanny py_macro_api py_c_api pyx_macro_api pyx_c_ap i error_goto'.split())
136
137 def annotate(match):
138 group_name = match.lastgroup
139 calls[group_name] += 1
140 return ur"<span class='%s'>%s</span>" % (
141 group_name, match.group(group_name))
142
143 pos_comment_marker = u'/* \N{HORIZONTAL ELLIPSIS} */\n'
144 k = 0
145 code_source_file = self.code.get(source_filename, {})
146 for line in lines:
147 k += 1
148 try:
149 code = code_source_file[k]
150 except KeyError:
151 code = ''
152 else:
153 code = _replace_pos_comment(pos_comment_marker, code)
154 if code.startswith(pos_comment_marker):
155 code = code[len(pos_comment_marker):]
156 code = html_escape(code)
157
158 calls = zero_calls.copy()
159 code = _parse_code(annotate, code)
160 score = (5 * calls['py_c_api'] + 2 * calls['pyx_c_api'] +
161 calls['py_macro_api'] + calls['pyx_macro_api'])
162 color = u"FFFF%02x" % int(255/(1+score/10.0))
163 f.write(u"<pre class='line' style='background-color: #%s' onclick='t oggleDiv(\"line%s\")'>" % (color, k))
164
165 f.write(u" %d: " % k)
166 for c, cc, html in special_chars:
167 line = line.replace(cc, html)
168 f.write(line.rstrip())
169
170 f.write(u'</pre>\n')
171 f.write(u"<pre id='line%s' class='code' style='background-color: #%s '>%s</pre>" % (k, color, code))
172 f.write(u'</body></html>\n')
173 f.close()
174
175
176 _parse_code = re.compile(
177 ur'(?P<refnanny>__Pyx_X?(?:GOT|GIVE)REF|__Pyx_RefNanny[A-Za-z]+)|'
178 ur'(?:'
179 ur'(?P<pyx_macro_api>__Pyx_[A-Z][A-Z_]+)|'
180 ur'(?P<pyx_c_api>__Pyx_[A-Z][a-z_][A-Za-z_]+)|'
181 ur'(?P<py_macro_api>Py[A-Z][a-z]+_[A-Z][A-Z_]+)|'
182 ur'(?P<py_c_api>Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)'
183 ur')(?=\()|' # look-ahead to exclude subsequent '(' from replacement
184 ur'(?P<error_goto>(?:(?<=;) *if .* +)?\{__pyx_filename = .*goto __pyx_L\w+;\ })'
185 ).sub
186
187
188 _replace_pos_comment = re.compile(
189 # this matches what Cython generates as code line marker comment
190 ur'^\s*/\*(?:(?:[^*]|\*[^/])*\n)+\s*\*/\s*\n',
191 re.M
192 ).sub
193
194
195 class AnnotationItem(object):
196
197 def __init__(self, style, text, tag="", size=0):
198 self.style = style
199 self.text = text
200 self.tag = tag
201 self.size = size
202
203 def start(self):
204 return u"<span class='tag %s' title='%s'>%s" % (self.style, self.text, s elf.tag)
205
206 def end(self):
207 return self.size, u"</span>"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698