/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * (C) Copyright IBM Corporation 2006-2012. */ package x10c.visit; import java.io.IOException; import java.io.PrintStream; import polyglot.frontend.Job; import polyglot.util.CodeWriter; public class DebugCodeWriter extends CodeWriter { private final CodeWriter w; private final String name; private PrintStream html; public DebugCodeWriter(CodeWriter w, Job job) { String htmlname = job.source().name().replaceFirst(".x10", ".html"); if (htmlname.equals(job.source().name())) // double check to prevent overwriting the source htmlname = htmlname + ".html"; name = htmlname; try { html = new PrintStream(name); } catch (IOException e) { html = System.err; } html.println("<html><head>"); //html.println("<meta http-equiv='Refresh' content='20'/>"); html.println("<style type='text/css'>\n" + " a:hover {\n" + " background-color: #ccccff;\n" + " }\n" + " a.a { position: relative; }\n" + " a.a span {\n" + " border: dotted 2px #cccccc;\n" + " background-color: #00ffff;\n" + " display: none;\n" + " z-index: 1;\n" + " position: absolute; top: 1em; left: 0px;\n" + " font-size: smaller;\n" + " }\n" + "</style>"); html.println("<script type='text/javascript'>\n" + "\n" + "function toggle() {\n" + " h = this.getElementsByTagName('span')[0];\n" + " if (h.style.display == 'block') {\n" + " h.style.display = 'none';\n" + " } else {\n" + " h.style.display = 'block';\n" + " }\n" + "}\n" + "\n" + "function setup() {\n" + " elements = document.getElementsByTagName('a')\n" + " for (var i = 0; i < elements.length; i++) {\n" + " elt = elements[i];\n" + " if (elt.className != 'a') continue;\n" + " elt.onclick = toggle;\n" + " }\n" + "}\n" + "\n" + "</script>\n" + ""); html.println("</head><body onload='setup();'>"); html.println("<pre>"); this.w = w; } public void allowBreak(int n, int level, String alt, int altlen) { w.allowBreak(n, level, alt, altlen); html.print(alt); } public void allowBreak(int n, String alt) { w.allowBreak(n, alt); } public void allowBreak(int n) { w.allowBreak(n); } public void begin(int n) { w.begin(n); } public void close() throws IOException { try { w.close(); } finally { html.println("</pre></body></html>"); if (html != System.err) html.close(); } } public void end() { w.end(); } public boolean equals(Object arg0) { return w.equals(arg0); } public boolean flush() throws IOException { return w.flush(); } public boolean flush(boolean format) throws IOException { return w.flush(format); } public int hashCode() { return w.hashCode(); } public void newline() { w.newline(); html.println(); } public void newline(int n, int level) { w.newline(n, level); html.println(); } public void newline(int n) { w.newline(n); html.println(); } public String toString() { return w.toString(); } public void unifiedBreak(int n, int level, String alt, int altlen) { w.unifiedBreak(n, level, alt, altlen); } public void unifiedBreak(int n) { w.unifiedBreak(n); } public void write(String s, int length) { w.write(s, length); html.print(html_escape(s)); } public void write(String s) { //if (name.equals("polyglot.util.OptimalCodeWriter")) { StackTraceElement[] stackTrace = new Exception().getStackTrace(); StringBuffer sb = new StringBuffer(); for (int i = 1; i < Math.min(60, stackTrace.length); i++) { sb.append("<br/>"); sb.append(stackTrace[i].toString()); } String stack = sb.toString(); // hide location as a stack tooltip if (s.startsWith("/*location:")) { stack = s.substring("/*location:".length(), s.indexOf("*/")); s = s.substring(s.indexOf("*/") + 2); } html.print("<a class='a'>" + html_escape(s) + "<span>" + stack + "</span></a>"); w.write(s); } public static String html_escape(String s) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); switch (c) { case '<': sb.append("<"); break; case '>': sb.append(">"); break; case '&': sb.append("&"); break; default: sb.append(c); } } return sb.toString(); } }