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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/cython/src/Cython/Compiler/Annotate.py
diff --git a/third_party/cython/src/Cython/Compiler/Annotate.py b/third_party/cython/src/Cython/Compiler/Annotate.py
new file mode 100644
index 0000000000000000000000000000000000000000..4bbdeccfb3f81a1f6768f212ff67ed481bed2642
--- /dev/null
+++ b/third_party/cython/src/Cython/Compiler/Annotate.py
@@ -0,0 +1,207 @@
+# Note: Work in progress
+
+import os
+import re
+import codecs
+from xml.sax.saxutils import escape as html_escape
+from StringIO import StringIO
+
+import Version
+from Code import CCodeWriter
+from Cython import Utils
+
+# need one-characters subsitutions (for now) so offsets aren't off
+special_chars = [
+ (u'&', u'\xF2', u'&'),
+ (u'<', u'\xF0', u'&lt;'),
+ (u'>', u'\xF1', u'&gt;'),
+]
+
+
+class AnnotationCCodeWriter(CCodeWriter):
+
+ def __init__(self, create_from=None, buffer=None, copy_formatting=True):
+ CCodeWriter.__init__(self, create_from, buffer, copy_formatting=True)
+ if create_from is None:
+ self.annotation_buffer = StringIO()
+ self.annotations = []
+ self.last_pos = None
+ self.code = {}
+ else:
+ # When creating an insertion point, keep references to the same database
+ self.annotation_buffer = create_from.annotation_buffer
+ self.annotations = create_from.annotations
+ self.code = create_from.code
+ self.last_pos = create_from.last_pos
+
+ def create_new(self, create_from, buffer, copy_formatting):
+ return AnnotationCCodeWriter(create_from, buffer, copy_formatting)
+
+ def write(self, s):
+ CCodeWriter.write(self, s)
+ self.annotation_buffer.write(s)
+
+ def mark_pos(self, pos):
+ if pos is not None:
+ CCodeWriter.mark_pos(self, pos)
+ if self.last_pos:
+ pos_code = self.code.setdefault(self.last_pos[0].filename,{})
+ code = pos_code.get(self.last_pos[1], "")
+ pos_code[self.last_pos[1]] = code + self.annotation_buffer.getvalue()
+ self.annotation_buffer = StringIO()
+ self.last_pos = pos
+
+ def annotate(self, pos, item):
+ self.annotations.append((pos, item))
+
+ def save_annotation(self, source_filename, target_filename):
+ self.mark_pos(None)
+ f = Utils.open_source_file(source_filename)
+ lines = f.readlines()
+ for k, line in enumerate(lines):
+ for c, cc, html in special_chars:
+ line = line.replace(c, cc)
+ lines[k] = line
+ f.close()
+ all = []
+ if False:
+ for pos, item in self.annotations:
+ if pos[0].filename == source_filename:
+ start = item.start()
+ size, end = item.end()
+ if size:
+ all.append((pos, start))
+ all.append(((source_filename, pos[1], pos[2]+size), end))
+ else:
+ all.append((pos, start+end))
+
+ all.sort(reverse=True)
+ for pos, item in all:
+ _, line_no, col = pos
+ line_no -= 1
+ col += 1
+ line = lines[line_no]
+ lines[line_no] = line[:col] + item + line[col:]
+
+ html_filename = os.path.splitext(target_filename)[0] + ".html"
+ f = codecs.open(html_filename, "w", encoding="UTF-8")
+ f.write(u'<!DOCTYPE html>\n')
+ f.write(u'<!-- Generated by Cython %s -->\n' % Version.watermark)
+ f.write(u'<html>\n')
+ f.write(u"""
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+
+body { font-family: courier; font-size: 12; }
+
+.code { font-size: 9; color: #444444; display: none; margin-left: 20px; }
+.py_c_api { color: red; }
+.py_macro_api { color: #FF7000; }
+.pyx_c_api { color: #FF3000; }
+.pyx_macro_api { color: #FF7000; }
+.refnanny { color: #FFA000; }
+
+.error_goto { color: #FFA000; }
+
+.tag { }
+
+.coerce { color: #008000; border: 1px dotted #008000 }
+
+.py_attr { color: #FF0000; font-weight: bold; }
+.c_attr { color: #0000FF; }
+
+.py_call { color: #FF0000; font-weight: bold; }
+.c_call { color: #0000FF; }
+
+.line { margin: 0em }
+
+</style>
+<script>
+function toggleDiv(id) {
+ theDiv = document.getElementById(id);
+ if (theDiv.style.display != 'block') theDiv.style.display = 'block';
+ else theDiv.style.display = 'none';
+}
+</script>
+</head>
+ """)
+ f.write(u'<body>\n')
+ f.write(u'<p>Generated by Cython %s\n' % Version.watermark)
+ c_file = Utils.decode_filename(os.path.basename(target_filename))
+ f.write(u'<p>Raw output: <a href="%s">%s</a>\n' % (c_file, c_file))
+
+ zero_calls = dict((name, 0) for name in
+ 'refnanny py_macro_api py_c_api pyx_macro_api pyx_c_api error_goto'.split())
+
+ def annotate(match):
+ group_name = match.lastgroup
+ calls[group_name] += 1
+ return ur"<span class='%s'>%s</span>" % (
+ group_name, match.group(group_name))
+
+ pos_comment_marker = u'/* \N{HORIZONTAL ELLIPSIS} */\n'
+ k = 0
+ code_source_file = self.code.get(source_filename, {})
+ for line in lines:
+ k += 1
+ try:
+ code = code_source_file[k]
+ except KeyError:
+ code = ''
+ else:
+ code = _replace_pos_comment(pos_comment_marker, code)
+ if code.startswith(pos_comment_marker):
+ code = code[len(pos_comment_marker):]
+ code = html_escape(code)
+
+ calls = zero_calls.copy()
+ code = _parse_code(annotate, code)
+ score = (5 * calls['py_c_api'] + 2 * calls['pyx_c_api'] +
+ calls['py_macro_api'] + calls['pyx_macro_api'])
+ color = u"FFFF%02x" % int(255/(1+score/10.0))
+ f.write(u"<pre class='line' style='background-color: #%s' onclick='toggleDiv(\"line%s\")'>" % (color, k))
+
+ f.write(u" %d: " % k)
+ for c, cc, html in special_chars:
+ line = line.replace(cc, html)
+ f.write(line.rstrip())
+
+ f.write(u'</pre>\n')
+ f.write(u"<pre id='line%s' class='code' style='background-color: #%s'>%s</pre>" % (k, color, code))
+ f.write(u'</body></html>\n')
+ f.close()
+
+
+_parse_code = re.compile(
+ ur'(?P<refnanny>__Pyx_X?(?:GOT|GIVE)REF|__Pyx_RefNanny[A-Za-z]+)|'
+ ur'(?:'
+ ur'(?P<pyx_macro_api>__Pyx_[A-Z][A-Z_]+)|'
+ ur'(?P<pyx_c_api>__Pyx_[A-Z][a-z_][A-Za-z_]+)|'
+ ur'(?P<py_macro_api>Py[A-Z][a-z]+_[A-Z][A-Z_]+)|'
+ ur'(?P<py_c_api>Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)'
+ ur')(?=\()|' # look-ahead to exclude subsequent '(' from replacement
+ ur'(?P<error_goto>(?:(?<=;) *if .* +)?\{__pyx_filename = .*goto __pyx_L\w+;\})'
+).sub
+
+
+_replace_pos_comment = re.compile(
+ # this matches what Cython generates as code line marker comment
+ ur'^\s*/\*(?:(?:[^*]|\*[^/])*\n)+\s*\*/\s*\n',
+ re.M
+).sub
+
+
+class AnnotationItem(object):
+
+ def __init__(self, style, text, tag="", size=0):
+ self.style = style
+ self.text = text
+ self.tag = tag
+ self.size = size
+
+ def start(self):
+ return u"<span class='tag %s' title='%s'>%s" % (self.style, self.text, self.tag)
+
+ def end(self):
+ return self.size, u"</span>"

Powered by Google App Engine
This is Rietveld 408576698