view src/luan/LuanException.java @ 1267:9fa8b8389578

add LuanTable.luan; support metatable __gc(); add luan.sql;
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 12 Nov 2018 02:10:41 -0700
parents 442abdfff437
children 2531942abaf3
line wrap: on
line source

package luan;

import java.io.StringWriter;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.List;
import java.util.ArrayList;


public final class LuanException extends Exception implements LuanCloneable {
	private LuanTable table;

	public LuanException(String msg,Throwable cause) {
		super(msg,cause);
	}

	public LuanException(String msg) {
		super(msg);
	}

	public LuanException(Throwable cause) {
		super(cause);
	}

	private LuanException(String msg,Throwable cause,int nonsense) {
		super(msg,cause);
	}

	@Override public LuanException shallowClone() {
		return new LuanException(getMessage(),getCause(),99);
	}

	@Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
		LuanException clone = (LuanException)dc;
		clone.table = (LuanTable)cloner.clone(table);
	}

	public LuanTable table(LuanState luan) {
		if( table==null ) {
			table = new LuanTable(luan);
			table.rawPut( "java", this );
			LuanTable metatable = new LuanTable(luan);
			table.setMetatable(metatable);
			try {
				table.rawPut( "get_message", new LuanJavaFunction(
					LuanException.class.getMethod( "getMessage" ), this
				) );
				table.rawPut( "throw", new LuanJavaFunction(
					LuanException.class.getMethod( "throwThis" ), this
				) );
				table.rawPut( "get_stack_trace_string", new LuanJavaFunction(
					LuanException.class.getMethod( "getLuanStackTraceString" ), this
				) );
				table.rawPut( "get_java_stack_trace_string", new LuanJavaFunction(
					LuanException.class.getMethod( "getJavaStackTraceString" ), this
				) );
				metatable.rawPut( "__to_string", new LuanJavaFunction(
					LuanException.class.getMethod( "__to_string", LuanTable.class ), this
				) );
			} catch(NoSuchMethodException e) {
				throw new RuntimeException(e);
			}
		}
		return table;
	}

	public void throwThis() throws LuanException {
		throw this;
	}

	public String __to_string(LuanTable ignore) {
		return getLuanStackTraceString();
	}

	public String getJavaStackTraceString() {
		return getJavaStackTraceString(this);
	}

	private static String getJavaStackTraceString(Throwable th) {
		StringWriter sw = new StringWriter();
		th.printStackTrace(new PrintWriter(sw));
		return sw.toString();
	}

	public static List<StackTraceElement> justLuan(StackTraceElement[] orig) {
		List<StackTraceElement> list = new ArrayList<StackTraceElement>();
		for( int i=0; i<orig.length; i++ ) {
			StackTraceElement ste = orig[i];
			if( !ste.getClassName().startsWith("luan.impl.EXP") )
				continue;
			list.add(ste);
			if( !ste.getMethodName().equals("doCall") )
				i++;
		}
		return list;
	}

	public static String toString(StackTraceElement ste) {
		StringBuilder sb = new StringBuilder();
		sb.append( ste.getFileName() ).append( " line " ).append( ste.getLineNumber() );
		String method = ste.getMethodName();
		if( !method.equals("doCall") )
			sb.append( " in function '" ).append( method.substring(1) ).append( "'" );
		return sb.toString();
	}

	private StringBuilder luanStackTrace() {
		StringBuilder sb = new StringBuilder();
		sb.append( getMessage() );
		for( StackTraceElement ste : justLuan(getStackTrace()) ) {
			sb.append( "\n\t" ).append( toString(ste) );
		}
		return sb;
	}

	public String getLuanStackTraceString() {
		StringBuilder sb = luanStackTrace();
		Throwable cause = getCause();
		if( cause != null )
			sb.append( "\nCaused by: " ).append( getJavaStackTraceString(cause) );
		return sb.toString();
	}

	public static String currentSource() {
		LuanException ex = new LuanException("currentSource");
		List<StackTraceElement> st = ex.justLuan(ex.getStackTrace());
		return st.isEmpty() ? null : st.get(0).getFileName();
	}

	@Override public void printStackTrace(PrintStream s) {
		s.print("Luan: ");
		s.println(luanStackTrace());
		s.print("Caused by: ");
		super.printStackTrace(s);
	}

	@Override public void printStackTrace(PrintWriter s) {
		s.print("Luan: ");
		s.println(luanStackTrace());
		s.print("Caused by: ");
		super.printStackTrace(s);
	}

}