Changing Decompiler.decompile to take just encoded source, flag argument controlling output format and property table so it would be possible to add more options to decompiler without changing the rest of code.

This commit is contained in:
igor%mir2.org 2003-11-12 12:22:12 +00:00
Родитель 86b7ac3792
Коммит fa80cda516
8 изменённых файлов: 71 добавлений и 51 удалений

Просмотреть файл

@ -182,7 +182,7 @@ public class BaseFunction extends IdScriptable implements Function {
int indent = ScriptRuntime.toInt32(args, 0); int indent = ScriptRuntime.toInt32(args, 0);
Object x = thisObj.getDefaultValue(ScriptRuntime.FunctionClass); Object x = thisObj.getDefaultValue(ScriptRuntime.FunctionClass);
if (x instanceof BaseFunction) { if (x instanceof BaseFunction) {
return ((BaseFunction)x).decompile(cx, indent, false); return ((BaseFunction)x).decompile(cx, indent, 0);
} }
throw ScriptRuntime.typeError1("msg.incompat.call", "toString"); throw ScriptRuntime.typeError1("msg.incompat.call", "toString");
} }
@ -279,16 +279,16 @@ public class BaseFunction extends IdScriptable implements Function {
* Decompile the source information associated with this js * Decompile the source information associated with this js
* function/script back into a string. * function/script back into a string.
* *
* @param cx Current context * @param cx Current context.
* *
* @param indent How much to indent the decompiled result * @param indent How much to indent the decompiled result.
* *
* @param justbody Whether the decompilation should omit the * @param flags Flags specifying format of decompilation output.
* function header and trailing brace.
*/ */
public String decompile(Context cx, int indent, int flags)
public String decompile(Context cx, int indent, boolean justbody) { {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
if (!justbody) { if (!justbody) {
sb.append("function "); sb.append("function ");
sb.append(getFunctionName()); sb.append(getFunctionName());

Просмотреть файл

@ -1115,7 +1115,7 @@ public class Context
int indent) int indent)
{ {
NativeFunction scriptImpl = (NativeFunction) script; NativeFunction scriptImpl = (NativeFunction) script;
return scriptImpl.decompile(this, indent, false); return scriptImpl.decompile(this, indent, 0);
} }
/** /**
@ -1133,7 +1133,7 @@ public class Context
*/ */
public String decompileFunction(Function fun, int indent) { public String decompileFunction(Function fun, int indent) {
if (fun instanceof BaseFunction) if (fun instanceof BaseFunction)
return ((BaseFunction)fun).decompile(this, indent, false); return ((BaseFunction)fun).decompile(this, indent, 0);
else else
return "function " + fun.getClassName() + return "function " + fun.getClassName() +
"() {\n\t[native code]\n}\n"; "() {\n\t[native code]\n}\n";
@ -1153,12 +1153,12 @@ public class Context
* @return a string representing the function body source. * @return a string representing the function body source.
*/ */
public String decompileFunctionBody(Function fun, int indent) { public String decompileFunctionBody(Function fun, int indent) {
if (fun instanceof BaseFunction) if (fun instanceof BaseFunction) {
return ((BaseFunction)fun).decompile(this, indent, true); BaseFunction bf = (BaseFunction)fun;
else return bf.decompile(this, indent, Decompiler.ONLY_BODY_FLAG);
// not sure what the right response here is. JSRef currently }
// dumps core. // ALERT: not sure what the right response here is.
return "[native code]\n"; return "[native code]\n";
} }
/** /**

Просмотреть файл

@ -72,14 +72,31 @@ package org.mozilla.javascript;
*/ */
public class Decompiler public class Decompiler
{ {
/**
* Flag to indicate that the decompilation should omit the
* function header and trailing brace.
*/
public static final int ONLY_BODY_FLAG = 1 << 0;
/**
* Decompilation property to specify initial ident value.
*/
public static final int INITIAL_INDENT_PROP = 1;
/**
* Decompilation property to specify default identation offset.
*/
public static final int INDENT_GAP_PROP = 2;
/**
* Decompilation property to specify identation offset for case labels.
*/
public static final int CASE_GAP_PROP = 3;
// Marker to denote the last RC of function so it can be distinguished from // Marker to denote the last RC of function so it can be distinguished from
// the last RC of object literals in case of function expressions // the last RC of object literals in case of function expressions
private static final int FUNCTION_END = Token.LAST_TOKEN + 1; private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
public Decompiler()
{
}
String getEncodedSource() String getEncodedSource()
{ {
return sourceToString(0); return sourceToString(0);
@ -259,34 +276,28 @@ public class Decompiler
* mapping the original source to the prettyprinted decompiled * mapping the original source to the prettyprinted decompiled
* version is done by the parser. * version is done by the parser.
* *
* Note that support for Context.decompileFunctionBody is hacked * @param source encoded source tree presentation
* on through special cases; I suspect that js makes a distinction
* between function header and function body that rhino
* decompilation does not.
* *
* @param encodedSourcesTree See {@link NativeFunction#getSourcesTree()} * @param flags flags to select output format
* for definition
* *
* @param justbody Whether the decompilation should omit the * @param properties indentation properties
* function header and trailing brace.
*
* @param indent How much to indent the decompiled result
*
* @param indentGap the default identation offset
*
* @param indentGap the identation offset for case labels
* *
*/ */
public static String decompile(Object sourceObj, public static String decompile(String source, int flags,
boolean justFunctionBody, UintMap properties)
int indent, int indentGap, int caseGap)
{ {
String source = (String)sourceObj;
int length = source.length(); int length = source.length();
if (length == 0) { return ""; } if (length == 0) { return ""; }
int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
if (indent < 0) Kit.badArg();
int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
if (indentGap < 0) Kit.badArg();
int caseGap = properties.getInt(CASE_GAP_PROP, 2);
if (caseGap < 0) Kit.badArg();
StringBuffer result = new StringBuffer(); StringBuffer result = new StringBuffer();
boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
// Spew tokens in source, for debugging. // Spew tokens in source, for debugging.
// as TYPE number char // as TYPE number char

Просмотреть файл

@ -105,9 +105,10 @@ public class IdFunction extends BaseFunction
throw ScriptRuntime.typeError1("msg.not.ctor", functionName); throw ScriptRuntime.typeError1("msg.not.ctor", functionName);
} }
public String decompile(Context cx, int indent, boolean justbody) public String decompile(Context cx, int indent, int flags)
{ {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
if (!justbody) { if (!justbody) {
sb.append("function "); sb.append("function ");
sb.append(getFunctionName()); sb.append(getFunctionName());

Просмотреть файл

@ -360,7 +360,17 @@ public class Kit
public static RuntimeException codeBug() public static RuntimeException codeBug()
throws RuntimeException throws RuntimeException
{ {
throw new RuntimeException("FAILED ASSERTION"); throw new IllegalStateException("FAILED ASSERTION");
}
/**
* Convinient way to throw IllegalArgumentException to indicate bad
* argument.
*/
public static void badArg()
throws IllegalArgumentException
{
throw new IllegalArgumentException();
} }
} }

Просмотреть файл

@ -71,19 +71,17 @@ public class NativeFunction extends BaseFunction
* *
* @param indent How much to indent the decompiled result * @param indent How much to indent the decompiled result
* *
* @param justbody Whether the decompilation should omit the * @param flags Flags specifying format of decompilation output
* function header and trailing brace.
*/ */
public final String decompile(Context cx, int indent, boolean justbody) public final String decompile(Context cx, int indent, int flags)
{ {
String encodedSource = getEncodedSource(); String encodedSource = getEncodedSource();
if (encodedSource == null) { if (encodedSource == null) {
return super.decompile(cx, indent, justbody); return super.decompile(cx, indent, flags);
} else { } else {
final int INDENT_GAP = 4; UintMap properties = new UintMap(1);
final int CASE_GAP = 2; // less how much for case labels properties.put(Decompiler.INITIAL_INDENT_PROP, indent);
return Decompiler.decompile(encodedSource, justbody, return Decompiler.decompile(encodedSource, flags, properties);
indent, INDENT_GAP, CASE_GAP);
} }
} }

Просмотреть файл

@ -107,9 +107,10 @@ public class NativeJavaMethod extends BaseFunction
return sig.toString(); return sig.toString();
} }
public String decompile(Context cx, int indent, boolean justbody) public String decompile(Context cx, int indent, int flags)
{ {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
if (!justbody) { if (!justbody) {
sb.append("function "); sb.append("function ");
sb.append(getFunctionName()); sb.append(getFunctionName());

Просмотреть файл

@ -141,8 +141,7 @@ public class VariableModel extends AbstractTreeTableModel
String result; String result;
try { try {
if (value instanceof BaseFunction) { if (value instanceof BaseFunction) {
result = ((BaseFunction)value).decompile(cx, 0, result = ((BaseFunction)value).decompile(cx, 0, 0);
false);
} else { } else {
result = Context.toString(value); result = Context.toString(value);
} }