Commits

Antonio Cuni committed 1c320ed

highlight all the occurences of the variable the mouse is on. Tests are failing because they don't expect to receive HTML, I'll fix them later

Comments (0)

Files changed (4)

     app.debug = True
     app.route('/')(server.index)
     app.route('/loop')(server.loop)
-    th = start_browser('http://localhost:5000/')
+    #th = start_browser('http://localhost:5000/')
     app.run(use_reloader=False, host='0.0.0.0')
-    th.join()
+    #th.join()
 
 if __name__ == '__main__':
     main()
 
 def _new_binop(name):
     def f(self):
-        return '%s = %s %s %s' % (self.res, self.args[0], name, self.args[1])
+        return '%s = %s %s %s' % (self.getres(), self.getarg(0), name, self.getarg(1))
     return f
 
+class Html(str):
+    def __html__(self):
+        return self
+
+def cssclass(cls, s, **kwds):
+    attrs = ['%s="%s"' % (name, value) for name, value in kwds.iteritems()]
+    return '<span class="%s" %s>%s</span>' % (cls, ' '.join(attrs), s)
+
 class Op(object):
     bridge = None
     
         pass
 
     def html_repr(self):
-        return getattr(self, 'repr_' + self.name, self.generic_repr)()
+        return Html(getattr(self, 'repr_' + self.name, self.generic_repr)())
+
+    def getarg(self, i):
+        return self._getvar(self.args[i])
+
+    def getres(self):
+        return self._getvar(self.res)
+
+    def _getvar(self, v):
+        return cssclass(v, v, onmouseover='highlight_var(this)', onmouseout='disable_var(this)')
 
     def is_guard(self):
         return self._is_guard
         locals()['repr_' + name] = _new_binop(bin_op)
 
     def repr_guard_true(self):
-        return '%s is true' % self.args[0]
+        return '%s is true' % self.getarg(0)
 
     def repr_guard_false(self):
-        return '%s is false' % self.args[0]
+        return '%s is false' % self.getarg(0)
 
     def repr_guard_value(self):
-        return '%s is %s' % (self.args[0], self.args[1])
+        return '%s is %s' % (self.getarg(0), self.getarg(1))
 
     def repr_guard_isnull(self):
-        return '%s is null' % self.args[0]
+        return '%s is null' % self.getarg(0)
 
     def repr_getfield_raw(self):
         name, field = self.descr.split(' ')[1].rsplit('.', 1)
-        return '%s = ((%s)%s).%s' % (self.res, name, self.args[0], field[2:])
+        return '%s = ((%s)%s).%s' % (self.getres(), name, self.getarg(0), field[2:])
 
     def repr_getfield_gc(self):
-        name, field = self.descr.split(' ')[1].rsplit('.', 1)
-        return '%s = ((%s)%s).%s' % (self.res, name, self.args[0], field)
+        fullname, field = self.descr.split(' ')[1].rsplit('.', 1)
+        namespace, classname = fullname.rsplit('.', 1)
+        namespace = cssclass('namespace', namespace)
+        classname = cssclass('classname', classname)
+        field = cssclass('fieldname', field)
+        #obj = self.getarg(0)
+        obj = self.getarg(0)
+        return '%s = ((%s.%s)%s).%s' % (self.getres(), namespace, classname, obj, field)
     repr_getfield_gc_pure = repr_getfield_gc
 
     def repr_setfield_raw(self):
         name, field = self.descr.split(' ')[1].rsplit('.', 1)
-        return '((%s)%s).%s = %s' % (name, self.args[0], field[2:], self.args[1])
+        return '((%s)%s).%s = %s' % (name, self.getarg(0), field[2:], self.getarg(1))
 
     def repr_setfield_gc(self):
         name, field = self.descr.split(' ')[1].rsplit('.', 1)
-        return '((%s)%s).%s = %s' % (name, self.args[0], field, self.args[1])
+        return '((%s)%s).%s = %s' % (name, self.getarg(0), field, self.getarg(1))
 
     def generic_repr(self):
         if self.res is not None:
-            return '%s = %s(%s)' % (self.res, self.name, ', '.join(self.args))
+            return '%s = %s(%s)' % (self.getres(), self.name, ', '.join(self.args))
         else:
             return '%s(%s)' % (self.name, ', '.join(self.args))
 
     def __init__(self, operations, storage):
         if operations[0].name == 'debug_merge_point':
             m = re.search('<code object ([<>\w]+), file \'(.+?)\', line (\d+)> #(\d+) (\w+)',
-                         operations[0].args[0])
+                         operations[0].getarg(0))
             if m is None:
                 # a non-code loop, like StrLiteralSearch or something
-                self.bytecode_name = operations[0].args[0].split(" ")[0][1:]
+                self.bytecode_name = operations[0].getarg(0).split(" ")[0][1:]
             else:
                 self.name, self.filename, lineno, bytecode_no, self.bytecode_name = m.groups()
                 self.startlineno = int(lineno)
 function toggle()
 {
     $('.operations').toggle()
+}
+
+function highlight_var(elem)
+{
+    var cssclass = elem.className
+    var elems = document.getElementsByClassName(cssclass);
+   	for (var i=0; i<elems.length; i++) {
+        var elem = elems[i];
+        if (elem.className.search("variable_highlight") == -1)
+            elem.className += " variable_highlight";
+    }
+}
+
+function disable_var(elem)
+{
+    var cssclass = "variable_highlight";
+    var elems = document.getElementsByClassName(cssclass);
+    // the collections is mutated while the loop runs
+    while (elems.length > 0) {
+        var elem = elems[0];
+        elem.className = elem.className.replace(/variable_highlight/g, "");
+    }
 }
 .inlined_call {
 	display: inline-block;
 }
+
+.variable_highlight {
+    background-color: #FFA;
+}
+
+.namespace {
+    color: black;
+}
+
+.classname {
+    color: #A00;
+}
+
+.fieldname {
+    color: #00A;
+}
+
 /* End of Formatting 
 -----------------------------------------*/