Commit f942392e authored by andrei's avatar andrei

Improved stack/lvt view, fixed selections in verify mode, minor changes

parent 5dcc2db2
/*****************************************************************************************
* Copyright (c) 2004 Andrei Loskutov. All rights reserved. This program and the
* accompanying materials are made available under the terms of the BSD License which
* accompanies this distribution, and is available at
* http://www.opensource.org/licenses/bsd-license.php Contributor: Andrei Loskutov -
* initial API and implementation
****************************************************************************************/
package de.loskutov.bco;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The main plugin class to be used in the desktop.
*/
public class BytecodeOutlinePlugin extends AbstractUIPlugin {
//The shared instance.
private static BytecodeOutlinePlugin plugin;
//Resource bundle.
private ResourceBundle resourceBundle;
/** asm logo */
public static final String IMG_ASM = "icons/asm.gif"; //$NON-NLS-1$
/**
* The constructor.
*/
public BytecodeOutlinePlugin() {
super();
plugin = this;
try {
resourceBundle = ResourceBundle
.getBundle("de.loskutov.bco.BytecodeOutlinePluginResources"); //$NON-NLS-1$
} catch (MissingResourceException x) {
resourceBundle = null;
}
}
/**
* This method is called upon plug-in activation
* @param context
* @throws Exception
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/**
* This method is called when the plug-in is stopped
* @param context
* @throws Exception
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
}
/**
* Returns the shared instance.
* @return plugin
*/
public static BytecodeOutlinePlugin getDefault() {
return plugin;
}
/**
* Returns the string from the plugin's resource bundle, or 'key' if not found.
* @param key
* @return translation
*/
public static String getResourceString(String key) {
ResourceBundle bundle = BytecodeOutlinePlugin.getDefault()
.getResourceBundle();
try {
return (bundle != null)
? bundle.getString(key)
: key;
} catch (MissingResourceException e) {
return key;
}
}
/**
* Returns the plugin's resource bundle,
*/
private ResourceBundle getResourceBundle() {
return resourceBundle;
}
/**
* Returns the workspace instance.
* @return shell object
*/
public static Shell getShell() {
return getDefault().getWorkbench().getActiveWorkbenchWindow()
.getShell();
}
/**
* @param messageID
* @param error
*/
public static void error(String messageID, Throwable error) {
Shell shell = getShell();
String message = getResourceString("BytecodeOutline.Error"); //$NON-NLS-1$
if (messageID != null) {
message = getResourceString(messageID);
}
message = message + " " + error.getMessage();//$NON-NLS-1$
MessageDialog.openError(
shell, getResourceString("BytecodeOutline.Title"), //$NON-NLS-1$
message);
getDefault().getLog().log(
new Status(IStatus.ERROR, "BytecodeOutline", 0, message, error)); //$NON-NLS-1$
}
/**
* @param error
*/
public static void logError(Throwable error) {
String message = error.getMessage();
if(message == null){
message = error.toString();
}
getDefault().getLog()
.log(
new Status(
IStatus.ERROR,
"BytecodeOutline", 0, message, error)); //$NON-NLS-1$
}
/*****************************************************************************************
* Copyright (c) 2004 Andrei Loskutov. All rights reserved. This program and the
* accompanying materials are made available under the terms of the BSD License which
* accompanies this distribution, and is available at
* http://www.opensource.org/licenses/bsd-license.php Contributor: Andrei Loskutov -
* initial API and implementation
****************************************************************************************/
package de.loskutov.bco;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The main plugin class to be used in the desktop.
*/
public class BytecodeOutlinePlugin extends AbstractUIPlugin {
//The shared instance.
private static BytecodeOutlinePlugin plugin;
//Resource bundle.
private ResourceBundle resourceBundle;
/** asm logo */
public static final String IMG_ASM = "icons/asm.gif"; //$NON-NLS-1$
/**
* The constructor.
*/
public BytecodeOutlinePlugin() {
super();
plugin = this;
try {
resourceBundle = ResourceBundle
.getBundle("de.loskutov.bco.BytecodeOutlinePluginResources"); //$NON-NLS-1$
} catch (MissingResourceException x) {
resourceBundle = null;
}
}
/**
* This method is called upon plug-in activation
* @param context
* @throws Exception
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/**
* This method is called when the plug-in is stopped
* @param context
* @throws Exception
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
}
/**
* Returns the shared instance.
* @return plugin
*/
public static BytecodeOutlinePlugin getDefault() {
return plugin;
}
/**
* Returns the string from the plugin's resource bundle, or 'key' if not found.
* @param key
* @return translation
*/
public static String getResourceString(String key) {
ResourceBundle bundle = BytecodeOutlinePlugin.getDefault()
.getResourceBundle();
try {
return (bundle != null)
? bundle.getString(key)
: key;
} catch (MissingResourceException e) {
return key;
}
}
/**
* Returns the plugin's resource bundle,
*/
public ResourceBundle getResourceBundle() {
return resourceBundle;
}
/**
* Returns the workspace instance.
* @return shell object
*/
public static Shell getShell() {
return getDefault().getWorkbench().getActiveWorkbenchWindow()
.getShell();
}
/**
* @param messageID
* @param error
*/
public static void error(String messageID, Throwable error) {
Shell shell = getShell();
String message = getResourceString("BytecodeOutline.Error"); //$NON-NLS-1$
if (messageID != null) {
message = getResourceString(messageID);
}
message = message + " " + error.getMessage();//$NON-NLS-1$
MessageDialog.openError(
shell, getResourceString("BytecodeOutline.Title"), //$NON-NLS-1$
message);
getDefault().getLog().log(
new Status(IStatus.ERROR, "BytecodeOutline", 0, message, error)); //$NON-NLS-1$
}
/**
* @param error
*/
public static void logError(Throwable error) {
String message = error.getMessage();
if(message == null){
message = error.toString();
}
getDefault().getLog()
.log(
new Status(
IStatus.ERROR,
"BytecodeOutline", 0, message, error)); //$NON-NLS-1$
}
}
\ No newline at end of file
......@@ -9,4 +9,6 @@ BytecodeOutlineView.enableVerifier_tooltip=Shows the symbolic state of the execu
BytecodeOutline.Title=Bytecode Outline
BytecodeOutline.Error=Error (Bytecode Outline)
ToggleASMifierModeAction.toggleASMifierMode_text=Toggle ASMifier mode on/off
ToggleASMifierModeAction.toggleASMifierMode_tooltip=Switch between true bytecode and ASMifier java code view
\ No newline at end of file
ToggleASMifierModeAction.toggleASMifierMode_tooltip=Switch between true bytecode and ASMifier java code view
BytecodeOutlineView.lvt_tooltip=LVT
BytecodeOutlineView.stack_tooltip=STACK
......@@ -67,14 +67,20 @@ public class DecompiledClass {
return -1;
}
public String getFrame(final int decompiledLine) {
/**
*
* @param decompiledLine
* @return array with two elements, first is the local variables table,
* second is the operands stack content. "null" value could be returned too.
*/
public String [] getFrame(final int decompiledLine, final boolean showQualifiedNames) {
int currentDecompiledLine = 0;
for (int i = 0; i < text.size(); ++i) {
Object o = text.get(i);
if (o instanceof DecompiledMethod) {
DecompiledMethod m = (DecompiledMethod) o;
String frame = m.getFrame(decompiledLine
- currentDecompiledLine);
String [] frame = m.getFrame(decompiledLine
- currentDecompiledLine, showQualifiedNames);
if (frame != null) {
return frame;
}
......
......@@ -218,14 +218,20 @@ public class DecompiledMethod {
frame = frames[((Index) o).insn];
}
} else {
String locals = "";
String stack = "";
String locals = " ";
String stack = " ";
if (frame != null) {
StringBuffer buf = new StringBuffer();
appendFrame(buf, frame);
int p = buf.indexOf(" ");
locals = buf.substring(0, p);
if("".equals(locals)){
locals = " ";
}
stack = buf.substring(p + 1);
if("".equals(stack)){
stack = " ";
}
}
lines.add(new String[]{locals, stack, o.toString()});
frame = null;
......@@ -262,7 +268,7 @@ public class DecompiledMethod {
appendValue(buf, f.getStack(i));
}
} catch (AnalyzerException e) {
e.printStackTrace();
BytecodeOutlinePlugin.logError(e);
}
}
......@@ -281,10 +287,16 @@ public class DecompiledMethod {
: i.intValue();
}
public String getFrame(final int decompiledLine) {
/**
*
* @param decompiledLine
* @return array with two elements, first is the local variables table,
* second is the operands stack content. "null" value could be returned too.
*/
public String[] getFrame(final int decompiledLine, final boolean useQualifiedNames) {
Integer insn = (Integer) insns.get(new Integer(decompiledLine));
if (error != null && insn != null && insn.intValue() == errorInsn) {
return error;
return new String [] {error,error};
}
if (frames != null && insn != null) {
Frame f = frames[insn.intValue()];
......@@ -293,23 +305,50 @@ public class DecompiledMethod {
}
try {
StringBuffer buf = new StringBuffer();
StringBuffer localsBuf = new StringBuffer();
for (int i = 0; i < f.getLocals(); ++i) {
buf.append(f.getLocal(i)).append('\n');
String s = f.getLocal(i).toString();
appendTypeName(useQualifiedNames, localsBuf, s);
localsBuf.append('\n');
}
buf.append('\n');
StringBuffer stackBuf = new StringBuffer();
for (int i = 0; i < f.getStackSize(); ++i) {
buf.append(f.getStack(i)).append('\n');
String s = f.getStack(i).toString();
appendTypeName(useQualifiedNames, stackBuf, s);
stackBuf.append('\n');
}
return buf.toString();
return new String[] {localsBuf.toString(), stackBuf.toString()};
} catch (AnalyzerException e) {
e.printStackTrace();
BytecodeOutlinePlugin.logError(e);
}
}
return null;
}
/**
* Appends full type name or only simply name, depends on boolean flag.
*
* @param useQualifiedNames if false, then e.g. "Object" will be appended to
* buffer instead of "Ljava/lang/Object;" etc
* @param buf buffer to append
* @param s string with bytecode type name, like "Ljava/lang/Object;"
*/
private void appendTypeName(final boolean useQualifiedNames, StringBuffer buf, String s) {
if(!useQualifiedNames) {
int idx = s.lastIndexOf('/');
if(idx > 0){
// from "Ljava/lang/Object;" to "Object"
buf.append(s.substring(idx + 1, s.length() - 1));
return;
}
}
if("Lnull;".equals(s)){
buf.append("null");
} else {
buf.append(s);
}
}
public int getDecompiledLine(final int sourceLine) {
Integer i = (Integer) decompiledLines.get(new Integer(sourceLine));
return i == null
......
......@@ -114,6 +114,7 @@ public class BytecodeOutlineView extends ViewPart {
protected Composite verifyControl;
protected Table tableControl;
protected StyledText stackControl;
protected StyledText lvtControl;
protected JavaEditor javaEditor;
protected IJavaElement javaInput;
......@@ -188,6 +189,12 @@ public class BytecodeOutlineView extends ViewPart {
if (tableControl != null && !tableControl.isDisposed()) {
tableControl.setEnabled(on);
}
if(stackControl != null && !stackControl.isDisposed()){
stackControl.setEnabled(on);
}
if(lvtControl != null && !lvtControl.isDisposed()){
lvtControl.setEnabled(on);
}
showSelectedOnlyAction.setEnabled(on);
linkWithEditorAction.setEnabled(on);
selectionChangedAction.setEnabled(on);
......@@ -327,10 +334,27 @@ public class BytecodeOutlineView extends ViewPart {
new TableColumn(tableControl, SWT.LEFT);
new TableColumn(tableControl, SWT.LEFT);
tableControl.setLinesVisible(false);
tableControl.setHeaderVisible(false);
stackControl = new StyledText(verifyControl, SWT.H_SCROLL
tableControl.setHeaderVisible(false);
SashForm stackAndLvt = new SashForm(verifyControl, SWT.HORIZONTAL);
lvtControl = new StyledText(stackAndLvt, SWT.H_SCROLL
| SWT.V_SCROLL);
lvtControl.setEditable(false);
lvtControl.setToolTipText(BytecodeOutlinePlugin
.getResourceString("BytecodeOutlineView.lvt_tooltip"));
stackControl = new StyledText(stackAndLvt, SWT.H_SCROLL
| SWT.V_SCROLL);
stackControl.setEditable(false);
stackControl.setToolTipText(BytecodeOutlinePlugin
.getResourceString("BytecodeOutlineView.stack_tooltip"));
stackAndLvt.setWeights(new int[]{50, 50});
((SashForm) verifyControl).setWeights(new int[]{75, 25});
((StackLayout) stackComposite.getLayout()).topControl = textControl;
......@@ -518,6 +542,7 @@ public class BytecodeOutlineView extends ViewPart {
verifyControl = null;
tableControl = null;
stackControl = null;
lvtControl = null;
}
if (errorColor != null) {
errorColor.dispose();
......@@ -703,6 +728,12 @@ public class BytecodeOutlineView extends ViewPart {
if (tableControl != null && !tableControl.isDisposed()) {
setItems(null);
}
if(stackControl != null && !stackControl.isDisposed()){
stackControl.setText("");
}
if(lvtControl != null && !lvtControl.isDisposed()){
lvtControl.setText("");
}
currentSelection = null;
lastDecompiledResult = null;
lastDecompiledElement = null;
......@@ -793,13 +824,14 @@ public class BytecodeOutlineView extends ViewPart {
if (decompiledLine > 0) {
try {
if (verifyCode) {
tableControl.select(decompiledLine);
String frame = lastDecompiledResult
.getFrame(decompiledLine);
if (verifyCode) {
String [] frame = lastDecompiledResult
.getFrame(decompiledLine, showQualifiedNames);
if (frame != null) {
stackControl.setText(frame);
lvtControl.setText(frame[0]);
stackControl.setText(frame[1]);
}
tableControl.setSelection(decompiledLine);
} else {
int offsetAtLine = textControl
......@@ -842,9 +874,10 @@ public class BytecodeOutlineView extends ViewPart {
.getOffset(), lineInfo.getLength());
}
if (verifyCode) {
String frame = lastDecompiledResult.getFrame(decompiledLine);
String [] frame = lastDecompiledResult.getFrame(decompiledLine, showQualifiedNames);
if (frame != null) {
stackControl.setText(frame);
lvtControl.setText(frame[0]);
stackControl.setText(frame[1]);
}
}
} catch (Exception e) {
......@@ -1059,7 +1092,7 @@ public class BytecodeOutlineView extends ViewPart {
ConsoleMessages.getString("IOConsolePage.1"),
ConsoleMessages.getString("IOConsolePage.2"));
setGlobalAction(actionBars, ActionFactory.SELECT_ALL.getId(), action);
action = new TextViewerAction(textViewer, ITextOperationTarget.COPY);
action
.configureAction(
......@@ -1070,16 +1103,16 @@ public class BytecodeOutlineView extends ViewPart {
.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
action.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY);
setGlobalAction(actionBars, ActionFactory.COPY.getId(), action);
ResourceBundle bundle = ResourceBundle
.getBundle("org.eclipse.ui.internal.console.ConsoleMessages"); //$NON-NLS-1$
setGlobalAction(
actionBars, ActionFactory.FIND.getId(), new FindReplaceAction(
bundle, "find_replace_action.", this)); //$NON-NLS-1$
selectionActions.add(ActionFactory.COPY.getId());
selectionActions.add(ActionFactory.FIND.getId());
actionBars.updateActionBars();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment