view core/src/luan/LuanException.java @ 517:8dcf9e12446b

add Luan.on_luan_close()
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 27 May 2015 01:20:49 -0600
parents 2e17b54e69d9
children f99c79b0b426
line wrap: on
line source

package luan;

import java.io.StringWriter;
import java.io.PrintWriter;


public final class LuanException extends Exception implements DeepCloneable {
	private LuanTable table = new LuanTable();

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

	LuanException(LuanBit bit,Object msg) throws LuanException {
		this( bit.luan.toString(msg), msg instanceof Throwable ? (Throwable)msg : null );
		table.rawPut("java",this);
		table.rawPut("message",msg);
		for( StackTraceElement ste : bit.stackTrace() ) {
			LuanTable tbl = new LuanTable();
			tbl.rawPut( "source", ste.call.source.name );
			tbl.rawPut( "line", ste.call.lineNumber() );
			tbl.rawPut( "call_to", ste.fnName );
			table.rawPut( table.rawLength() + 1, tbl );
		}
		LuanTable metatable = new LuanTable();
		table.setMetatable(metatable);
		try {
			table.rawPut( "throw", new LuanJavaFunction(
				LuanException.class.getMethod( "throwThis" ), this
			) );
			metatable.rawPut( "__to_string", new LuanJavaFunction(
				LuanException.class.getMethod( "__to_string", LuanState.class, LuanTable.class ), null
			) );
		} catch(NoSuchMethodException e) {
			throw new RuntimeException(e);
		}
	}

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

	@Override public void deepenClone(DeepCloneable dc,DeepCloner cloner) {
		LuanException clone = (LuanException)dc;
		clone.table = (LuanTable)cloner.get(table);
	}

	public LuanTable table() {
		return table;
	}

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

	public String getFullMessage(LuanState luan) {
		try {
			return __to_string(luan,table);
		} catch(LuanException e) {
			throw new RuntimeException(e);
		}
	}

	public static String __to_string(LuanState luan,LuanTable table) throws LuanException {
		StringBuilder buf = new StringBuilder();

		Object msg = table.rawGet("message");
		buf.append( luan.toString(msg) );

		for( int i = table.rawLength(); i>=1; i-- ) {
			LuanTable tbl = (LuanTable)table.rawGet(i);
			buf.append( "\n\t" ).append( tbl.rawGet("source") ).append( " line " ).append( tbl.rawGet("line") );
			Object callTo = tbl.rawGet("call_to");
			if( callTo != null )
				buf.append( " in call to '" ).append( callTo ).append( "'" );
		}

		if( msg instanceof Throwable ) {
			buf.append( "\nCaused by: " );
			Throwable cause = (Throwable)msg;
			StringWriter sw = new StringWriter();
			cause.printStackTrace(new PrintWriter(sw));
			buf.append( sw );
		}

		return buf.toString();
	}

}