package org.rascalmpl.library.experiments.Compiler.RVM.Interpreter; import java.io.PrintWriter; import org.rascalmpl.value.IConstructor; import org.rascalmpl.value.ISourceLocation; import org.rascalmpl.value.IValue; import org.rascalmpl.values.uptr.IRascalValueFactory; public class Thrown extends RuntimeException { private static final long serialVersionUID = 5789848344801944419L; // TODO: this is not thread safe private static Thrown instance = new Thrown(); public IValue value; private ISourceLocation loc; private Throwable cause; Frame currentFrame; private Thrown() { super(); this.setValue(null); this.currentFrame = null; this.cause = null; } public static Thrown getInstance(IValue value, ISourceLocation loc, Frame currentFrame) { instance.setValue(value); instance.loc = loc; instance.currentFrame = currentFrame; return instance; } public static Thrown getInstance(Throwable cause, ISourceLocation loc, Frame currentFrame) { instance.cause = cause; IRascalValueFactory vf = IRascalValueFactory.getInstance(); return getInstance(vf.node(cause.getClass().getCanonicalName(), vf.string(cause.getMessage())), loc, currentFrame); } public static Thrown getInstance(IValue value, Frame currentFrame) { return getInstance(value, currentFrame != null ? currentFrame.src : null, currentFrame); } public IValue getValue() { return value; } public void setValue(IValue value) { this.value = value; } public Frame getFrame(){ return currentFrame; } public String toString() { return getValue().toString(); } public String getAdvice(){ if(getValue().getType().isConstructor()){ String prefix = "http://tutor.rascal-mpl.org/Errors/Dynamic/"; String cn = ((IConstructor) getValue()).getName(); return "Advice: |" + prefix + cn + "/" + cn + ".html|"; } return ""; } public void printStackTrace(PrintWriter stdout) { if(currentFrame != null){ if(!currentFrame.isConsoleMainFrame()){ stdout.println(this.toString() + ((loc != null) ? " at " + loc : "") ); } while (cause != null) { stdout.println("Caused by (most recent first):"); for (StackTraceElement e : cause.getStackTrace()) { if (e.getMethodName().equals("invoke0")) { break; } String location = "|file:///" + e.getFileName() + "|(0,1,<" + e.getLineNumber() + ",1>,<" + e.getLineNumber() + ",1>)"; stdout.println("\t"+location +":" + e.getClassName() + "." + e.getMethodName() + "()"); } cause = cause.getCause() != cause ? getCause() : null; } if(currentFrame != null){ if(!currentFrame.isConsoleMainFrame()){ stdout.println("Call stack (most recent first):"); for(Frame f = currentFrame; f != null; f = f.previousCallFrame) { if(f.isConsoleMainFrame()){ stdout.println("\tinput from console"); } else { stdout.println("\t" + f); } } stdout.println(getAdvice()); } } else { stdout.println("No call stack available"); } } } }