Bug 492938 - [otdre] adjust debug representation for otdre
- retrieve real name for _OT$callOrig
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/META-INF/MANIFEST.MF
index a8fb19a..37d823e 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.objectteams.otdt.debug.adaptor;singleton:=true
Automatic-Module-Name: org.eclipse.objectteams.otdt.debug.adaptor
-Bundle-Version: 2.7.5.qualifier
+Bundle-Version: 2.8.2.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Require-Bundle: org.eclipse.jdt.core;bundle-version="[3.18.0.OTDT_r274,4.0.0)",
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/PresentationAdaptor.java b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/PresentationAdaptor.java
index 118dd54..3c2e50e 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/PresentationAdaptor.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/PresentationAdaptor.java
@@ -23,11 +23,15 @@
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IThread;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.debug.core.IJavaClassType;
+import org.eclipse.jdt.debug.core.IJavaReferenceType;
+import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.eclipse.jdt.internal.debug.ui.DebugUIMessages;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
@@ -51,6 +55,7 @@
public team class PresentationAdaptor
{
enum MethodKind {
+ UNKNOWN,
PLAIN,
INITIAL, CHAIN, ORIG, TEAM_WRAPPER, BASE_CALL, // callin related
LIFT,
@@ -79,27 +84,43 @@
protected class AbstractOTJStackFrame playedBy IJavaStackFrame {
// store analyzed method kind between calls:
- protected MethodKind kind= MethodKind.PLAIN;
+ protected MethodKind kind= MethodKind.UNKNOWN;
protected boolean isOTSpecialSrc() {
- OTDebugAdaptorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, OTDebugAdaptorPlugin.PLUGIN_ID, "Failed to create specific role for "+this.toString()));
+ OTDebugAdaptorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, OTDebugAdaptorPlugin.PLUGIN_ID, "Failed to create specific role for "+this.toString())); //$NON-NLS-1$
return false;
}
protected boolean isPurelyGenerated() {
- OTDebugAdaptorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, OTDebugAdaptorPlugin.PLUGIN_ID, "Failed to create specific role for "+this.toString()));
+ OTDebugAdaptorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, OTDebugAdaptorPlugin.PLUGIN_ID, "Failed to create specific role for "+this.toString())); //$NON-NLS-1$
return false;
}
public String toString() => String toString();
}
- @SuppressWarnings("unchecked")
+
protected class OTJStackFrame extends AbstractOTJStackFrame playedBy JDIStackFrame
{
// === imports: ===
+
+ // lifted access to the list of stack frames:
+ abstract int stackFramesCount() throws DebugException;
+ int stackFramesCount() -> IThread getThread() with { result <- ((JDIThread)result).computeStackFrames().size() }
+ abstract OTJStackFrame getStackFrameAt(int i) throws DebugException;
+ OTJStackFrame getStackFrameAt(int i) -> IThread getThread() with {
+ result <- (JDIStackFrame)((JDIThread)result).computeStackFrames().get(i)
+ }
+
boolean isStatic() -> boolean isStatic();
int modifiers() -> com.sun.jdi.Method getUnderlyingMethod()
with { result <- result.modifiers() }
+ // base versions of methods with callin interception:
+ String baseGetName() -> String getMethodName();
+ List<String> baseArgumentTypeNames() -> List<String> getArgumentTypeNames();
+ int baseLineNumber() -> int getLineNumber();
+
+ List<String> computedArgumentTypeNames; // here analyzeCallOrig() stores the signature of the matching INITIAL call
+
// == currently unused: ==
boolean isRole;
boolean isTeam;
@@ -139,7 +160,8 @@
}
}
- String getMethodName() <- replace String getMethodName();
+ String getMethodName() <- replace String getMethodName()
+ base when (!isExecutingCallin()); // no re-entrance, base method is called in this method's flow (via analyzeCallOrig())
@SuppressWarnings("nls")
callin String getMethodName() throws DebugException {
String result= base.getMethodName();
@@ -185,7 +207,8 @@
case CALL_ALL_BINDINGS:
return "[base dispatching callins]";
case CALL_ORIG:
- return "[executing base method]";
+ String realName = analyzeCallOrig();
+ return "[executing base method] "+realName;
default:
return result;
}
@@ -200,6 +223,7 @@
@SuppressWarnings("nls")
String[] analyzeMethod(String methodName)
{
+ this.kind = MethodKind.PLAIN; // no longer UNKNOWN
if (methodName != null && methodName.startsWith("_OT$"))
{
String[] segments= methodName.split("[$]");
@@ -226,6 +250,8 @@
this.kind= MethodKind.T_TERMINAL_CALL_NEXT;
else if (segments[1].equals("callOrig"))
this.kind= MethodKind.CALL_ORIG;
+ else if (segments[1].equals("access"))
+ this.kind= MethodKind.DECAPS;
break;
case 3:
if (segments[2].equals("orig")) // _OT$bm$orig
@@ -258,10 +284,42 @@
}
return null;
}
-
+
+ String analyzeCallOrig() throws DebugException {
+ // locates a matching INITIAL call below the current frame
+ // (respecting intermediate pairs of INITIAL & T_CALL_REPLACE)
+ int replaceCallinDepth = 0;
+ int frameCount = stackFramesCount();
+ int myIndex = -1;
+ for (int i = 0; i + 1 < frameCount; i++) {
+ OTJStackFrame frame = getStackFrameAt(i);
+ if (myIndex == -1 && frame == this) {
+ myIndex = i;
+ }
+ if (myIndex > -1) {
+ if (frame.kind == MethodKind.UNKNOWN)
+ frame.analyzeMethod(frame.baseGetName()); // main analysis
+ if (frame.kind == MethodKind.PLAIN)
+ frame.baseLineNumber(); // trigger analysis PLAIN/INITIAL
+
+ if (frame.kind == MethodKind.T_CALL_REPLACE) {
+ replaceCallinDepth++;
+ } else if (frame.kind == MethodKind.INITIAL) {
+ if (--replaceCallinDepth == 0) {
+ computedArgumentTypeNames = frame.baseArgumentTypeNames();
+ return frame.baseGetName();
+ }
+ }
+ }
+ }
+ return ""; //$NON-NLS-1$
+ }
+
getArgumentTypeNames <- replace getArgumentTypeNames;
- @SuppressWarnings("rawtypes")
- callin List getArgumentTypeNames() throws DebugException {
+ @SuppressWarnings("basecall")
+ callin List<String> getArgumentTypeNames() throws DebugException {
+ if (computedArgumentTypeNames != null)
+ return computedArgumentTypeNames;
return stripGeneratedParams(base.getArgumentTypeNames());
}
@@ -399,4 +457,23 @@
return labelText;
}
+
+// Unused snippet in case we ever need to read bytecode attributes for further presentation information:
+// try {
+// JDIType declaringType = (JDIType) getStackFrameAt(previousFrame).getReferenceType();
+// // FIXME: need to navigate to the enclosing team :(
+// byte[] constantPoolBytes = ((com.sun.jdi.ReferenceType) declaringType.getUnderlyingType()).constantPool();
+// ConstantPool constantPool = new ConstantPool(constantPoolBytes);
+// for (int i = 0; i < constantPool.getConstantPoolCount(); i++) {
+// if (constantPool.getEntryKind(i) == IConstantPoolConstant.CONSTANT_Utf8) {
+// IConstantPoolEntry entry = constantPool.decodeEntry(i);
+// if (entry.getStringValue().equals(new String(IOTConstants.OTSPECIAL_ACCESS))) {
+// System.out.println("found");
+// }
+// }
+// }
+//} catch (DebugException | ClassFormatException e) {
+// OTDebugAdaptorPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, OTDebugAdaptorPlugin.PLUGIN_ID, "Failed to retrieve class file attribute", e)); //$NON-NLS-1$
+//}
+
}