1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/micropython/report.py Sun Apr 18 21:10:41 2010 +0200
1.3 @@ -0,0 +1,261 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +View annotated sources.
1.8 +
1.9 +Copyright (C) 2006, 2007, 2010 Paul Boddie <paul@boddie.org.uk>
1.10 +
1.11 +This program is free software; you can redistribute it and/or modify it under
1.12 +the terms of the GNU General Public License as published by the Free Software
1.13 +Foundation; either version 3 of the License, or (at your option) any later
1.14 +version.
1.15 +
1.16 +This program is distributed in the hope that it will be useful, but WITHOUT
1.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.19 +details.
1.20 +
1.21 +You should have received a copy of the GNU General Public License along with
1.22 +this program. If not, see <http://www.gnu.org/licenses/>.
1.23 +"""
1.24 +
1.25 +from micropython.data import *
1.26 +from compiler.visitor import ASTVisitor
1.27 +import sys
1.28 +import os
1.29 +import textwrap
1.30 +
1.31 +# Classes.
1.32 +
1.33 +# HTML-related output production.
1.34 +
1.35 +html_header = """<?xml version="1.0" encoding="iso-8859-15"?>
1.36 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1.37 +<html xmlns="http://www.w3.org/1999/xhtml">
1.38 +<head>
1.39 + <title>Module</title>
1.40 + <style type="text/css">
1.41 + html {
1.42 + background-color: black; color: white;
1.43 + }
1.44 +
1.45 + body {
1.46 + padding-bottom: 4em;
1.47 + font-size: 14pt; font-family: monospace;
1.48 + background-color: black; color: white;
1.49 + }
1.50 +
1.51 + .nowrap { white-space: nowrap; }
1.52 +
1.53 + .class { margin-top: 1em; margin-bottom: 1em; }
1.54 + .function { margin-top: 1em; margin-bottom: 1em; }
1.55 + .body { padding-left: 2em; }
1.56 + .keyword { color: yellow; }
1.57 + .comment { color: blue; }
1.58 + .class-name { color: cyan; }
1.59 + .function-name { color: cyan; }
1.60 + .str { color: #FF00FF; }
1.61 + .doc { color: #FF00FF; margin-top: 1em; margin-bottom: 1em; }
1.62 + .invocation a { color: white; text-decoration: none; }
1.63 +
1.64 + .popup {
1.65 + display: none; z-index: 2;
1.66 + position: absolute; top: 2ex; left: 0;
1.67 + padding: 0.2em; background-color: #000000; color: white;
1.68 + border: 2px solid #dddddd;
1.69 + }
1.70 +
1.71 + .invocations {
1.72 + padding: 0.5em; background-color: #770000;
1.73 + clear: all;
1.74 + }
1.75 +
1.76 + .types {
1.77 + padding: 0.5em; background-color: #0000FF;
1.78 + float: right;
1.79 + }
1.80 +
1.81 + .raises {
1.82 + padding: 0.5em; background-color: #7700FF;
1.83 + float: right;
1.84 + }
1.85 +
1.86 + .scopes {
1.87 + padding: 0.5em; background-color: #007700;
1.88 + float: left;
1.89 + }
1.90 +
1.91 + .non-scopes {
1.92 + padding: 0.5em; background-color: #FF0000;
1.93 + float: left;
1.94 + }
1.95 +
1.96 + .no-types {
1.97 + background-color: #FF0000;
1.98 + }
1.99 +
1.100 + .op,
1.101 + .name,
1.102 + .attr,
1.103 + .conditional,
1.104 + .operator,
1.105 + .iterator,
1.106 + .call,
1.107 + .returns,
1.108 + .failure
1.109 + {
1.110 + position: relative;
1.111 + }
1.112 +
1.113 + .op:hover > .popup,
1.114 + .name:hover > .popup,
1.115 + .attr:hover > .popup,
1.116 + .conditional:hover > .popup,
1.117 + .operator:hover > .popup,
1.118 + .iterator:hover > .popup,
1.119 + .call:hover > .popup,
1.120 + .returns:hover > .popup,
1.121 + .failure:hover > .popup
1.122 + {
1.123 + display: block;
1.124 + }
1.125 +
1.126 + .summary-class {
1.127 + background-color: #004400;
1.128 + }
1.129 +
1.130 + .summary-instance {
1.131 + background-color: #0000FF;
1.132 + }
1.133 +
1.134 + .summary-attr {
1.135 + background-color: #007700;
1.136 + }
1.137 +
1.138 + </style>
1.139 +</head>
1.140 +<body>
1.141 +"""
1.142 +
1.143 +html_footer = """</body>
1.144 +</html>
1.145 +"""
1.146 +
1.147 +# Utility classes.
1.148 +
1.149 +class Writer:
1.150 +
1.151 + "A utility class providing useful HTML output methods."
1.152 +
1.153 + # Methods which return strings.
1.154 +
1.155 + def _text(self, text):
1.156 + return text.replace("&", "&").replace("<", "<").replace(">", ">")
1.157 +
1.158 + def _attr(self, attr):
1.159 + return self._text(attr).replace("'", "'").replace('"', """)
1.160 +
1.161 + def _url(self, url):
1.162 + return self._attr(url).replace("#", "%23").replace("-", "%2d")
1.163 +
1.164 + def _summary_link(self, module_name, name):
1.165 + return "<a href='%s-summary%sxhtml#%s'>%s</a>" % (module_name, os.path.extsep, self._attr(name), self._text(name))
1.166 +
1.167 + # Methods which write to the stream.
1.168 +
1.169 + def _comment(self, comment):
1.170 + self.stream.write("<span class='comment'># %s</span>\n" % comment)
1.171 +
1.172 + def _keyword(self, kw):
1.173 + self.stream.write("<span class='keyword'>%s</span> " % kw)
1.174 +
1.175 + def _doc(self, node):
1.176 + if node.doc is not None:
1.177 + self.stream.write("<pre class='doc'>\n")
1.178 + self.stream.write('"""')
1.179 + output = textwrap.dedent(node.doc.replace('"""', '\\"\\"\\"'))
1.180 + self.stream.write(self._text(output))
1.181 + self.stream.write('"""')
1.182 + self.stream.write("</pre>\n")
1.183 +
1.184 + def _name(self, name):
1.185 + self.stream.write("<span class='name'>%s</span>\n" % name)
1.186 +
1.187 +# Summary classes.
1.188 +
1.189 +class Summariser(Writer):
1.190 +
1.191 + def __init__(self, stream):
1.192 + self.stream = stream
1.193 +
1.194 + def process(self, module):
1.195 + self.module = module
1.196 + self._init_details()
1.197 + self.stream.write(html_header)
1.198 + self._write_classes(module)
1.199 + self.stream.write(html_footer)
1.200 +
1.201 + def _write_classes(self, module):
1.202 + self.stream.write("<table cellspacing='5' cellpadding='5'>\n")
1.203 +
1.204 + all_classes = {}
1.205 +
1.206 + for obj in self.module.all_objects:
1.207 + if isinstance(obj, Class):
1.208 + all_classes[obj.name] = obj
1.209 +
1.210 + all_class_names = all_classes.keys()
1.211 + all_class_names.sort()
1.212 +
1.213 + for name in all_class_names:
1.214 + self._write_class(all_classes[name])
1.215 +
1.216 + self.stream.write("</table>\n")
1.217 +
1.218 + def _write_class(self, obj):
1.219 +
1.220 + # Write the class...
1.221 +
1.222 + self.stream.write("<tbody class='class'>\n")
1.223 + self.stream.write("<tr>\n")
1.224 + self.stream.write("<th class='summary-class' id='%s'>\n" % obj.full_name())
1.225 + self._keyword("class")
1.226 + self.stream.write(obj.name)
1.227 + self.stream.write("</th>\n")
1.228 +
1.229 + # ...and all known attribute names.
1.230 +
1.231 + obj_attributes = obj.all_attribute_names()
1.232 +
1.233 + for name in self.attribute_names:
1.234 + if name in obj_attributes:
1.235 + self.stream.write("<th class='summary-attr'>%s</th>\n" % self._text(name))
1.236 + else:
1.237 + self.stream.write("<th></th>\n")
1.238 + self.stream.write("</tr>\n")
1.239 +
1.240 + self.stream.write("</tbody>\n")
1.241 +
1.242 + def _init_details(self):
1.243 + names = set()
1.244 +
1.245 + # Visit all classes.
1.246 +
1.247 + for obj in self.module.all_objects:
1.248 + if isinstance(obj, Class):
1.249 + names.update(obj.all_attribute_names())
1.250 +
1.251 + self.attribute_names = list(names)
1.252 + self.attribute_names.sort()
1.253 +
1.254 +# Convenience functions.
1.255 +
1.256 +def summary(module, filename):
1.257 + stream = open(filename, "wb")
1.258 + try:
1.259 + summariser = Summariser(stream)
1.260 + summariser.process(module)
1.261 + finally:
1.262 + stream.close()
1.263 +
1.264 +# vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/tests/abandoned_attribute_usage_multiple_candidates.py Sun Mar 28 01:12:15 2010 +0100
2.2 +++ b/tests/abandoned_attribute_usage_multiple_candidates.py Sun Apr 18 21:10:41 2010 +0200
2.3 @@ -2,9 +2,9 @@
2.4
2.5 """
2.6 This test attempts to cause the recording of the usage of 'C' in the function
2.7 -'f', alongside the expectation that 'D' might be used instead. A guard
2.8 -stipulating constraints for all of 'f' cannot therefore be generated. Meanwhile,
2.9 -the method 'E.h' should be eliminated.
2.10 +'f', alongside the expectation that 'D' might be used instead with the function
2.11 +'g'. A guard cannot therefore be generated. Meanwhile, the method 'E.h' should
2.12 +be eliminated.
2.13 """
2.14
2.15 class C:
3.1 --- a/tests/attribute_access_type_restriction_neither.py Sun Mar 28 01:12:15 2010 +0100
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,35 +0,0 @@
3.4 -#!/usr/bin/env python
3.5 -
3.6 -class C:
3.7 - def f(self):
3.8 - return 1
3.9 -
3.10 -class D:
3.11 - def f(self):
3.12 - return 2
3.13 -
3.14 - def g(self):
3.15 - return 3
3.16 -
3.17 -class E: # unused
3.18 - def f(self):
3.19 - return 4
3.20 -
3.21 - def h(self):
3.22 - return 5
3.23 -
3.24 -def test_neither(obj, obj2):
3.25 - # obj:
3.26 - # obj2:
3.27 - if 0:
3.28 - obj.g() # D (g)
3.29 - else:
3.30 - obj.f() # C, D, E (f)
3.31 - # # (g) ^ (f)
3.32 - return 4
3.33 -
3.34 -c = C()
3.35 -d = D()
3.36 -result1_4 = test_neither(c, d)
3.37 -
3.38 -# vim: tabstop=4 expandtab shiftwidth=4
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tests/failure/attribute_access_type_restriction_new_impossible.py Sun Apr 18 21:10:41 2010 +0200
4.3 @@ -0,0 +1,36 @@
4.4 +#!/usr/bin/env python
4.5 +
4.6 +class C:
4.7 + def f(self):
4.8 + return 1
4.9 +
4.10 +class D:
4.11 + def f(self):
4.12 + return 2
4.13 +
4.14 + def g(self): # unused
4.15 + return 3
4.16 +
4.17 +class E:
4.18 + def f(self):
4.19 + return 4
4.20 +
4.21 + def h(self):
4.22 + return 5
4.23 +
4.24 +def test_new(obj):
4.25 + # obj: C, D, E (f)
4.26 + if obj.f(): # C, D, E (f)
4.27 + obj2 = D() # obj2: E (h) -> conflict!
4.28 + obj2.h() # E (h)
4.29 + # else:
4.30 + # ... # obj: C, D, E (f)
4.31 + # # (f) ^ (f)
4.32 + return obj.f() # C, D, E (f)
4.33 +
4.34 +c = C()
4.35 +d = D()
4.36 +e = E()
4.37 +result2_2 = test_new(c)
4.38 +
4.39 +# vim: tabstop=4 expandtab shiftwidth=4