From 8c0f56fa80373c51e58bcd0312c08cb49013f09b Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Fri, 9 Aug 2002 21:52:37 +0000 Subject: [PATCH] More implementation. --- .../cdt/debug/internal/core/CDebugTarget.java | 37 +++ .../debug/internal/core/CLocalVariable.java | 178 +++++++++------ .../internal/core/CModificationVariable.java | 121 ++++++++++ .../cdt/debug/internal/core/CStackFrame.java | 15 +- .../cdt/debug/internal/core/CValue.java | 93 ++++++++ .../cdt/debug/internal/core/CVariable.java | 212 ++++++++++++++++++ 6 files changed, 585 insertions(+), 71 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CModificationVariable.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CValue.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CVariable.java diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugTarget.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugTarget.java index 14ba27a8427..4f8145d8e5a 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugTarget.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugTarget.java @@ -140,6 +140,11 @@ public class CDebugTarget extends CDebugElement */ private Object fCurrentStateInfo = null; + /** + * Count of the number of suspend events in this target + */ + private int fSuspendCount = 0; + /** * Constructor for CDebugTarget. * @param target @@ -1105,4 +1110,36 @@ public class CDebugTarget extends CDebugElement { fCurrentStateInfo = info; } + + /** + * Returns the number of suspend events that have occurred in this + * target. + * + * @return the number of suspend events that have occurred in this + * target + */ + protected int getSuspendCount() + { + return fSuspendCount; + } + + /** + * Increments the suspend counter for this target. + */ + protected void incrementSuspendCount() + { + fSuspendCount++; + } + + /** + * Overrides the superclass method by incrementing the suspend counter. + * + * @param detail The int detail of the event + * @see org.eclipse.debug.core.DebugEvent + */ + public void fireSuspendEvent( int detail ) + { + incrementSuspendCount(); + super.fireSuspendEvent( detail ); + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CLocalVariable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CLocalVariable.java index 52998c19a7d..ab1ca66602c 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CLocalVariable.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CLocalVariable.java @@ -3,30 +3,39 @@ * All Rights Reserved. * */ - package org.eclipse.cdt.debug.internal.core; +import java.text.MessageFormat; + +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.event.ICChangedEvent; import org.eclipse.cdt.debug.core.cdi.event.ICEvent; import org.eclipse.cdt.debug.core.cdi.event.ICEventListener; +import org.eclipse.cdt.debug.core.cdi.model.ICObject; +import org.eclipse.cdt.debug.core.cdi.model.ICValue; import org.eclipse.cdt.debug.core.cdi.model.ICVariable; +import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IValue; -import org.eclipse.debug.core.model.IVariable; /** * - * Proxy to a local variaable on the target. + * Enter type comment. * - * @since Aug 7, 2002 + * @since Aug 9, 2002 */ -public class CLocalVariable extends CDebugElement - implements IVariable, - ICEventListener +public class CLocalVariable extends CModificationVariable + implements ICEventListener { /** - * Underlying CDI variable. + * The underlying CDI variable. */ private ICVariable fCDIVariable; + + /** + * The stack frame this variable is contained in. + */ + private CStackFrame fStackFrame; /** * Constructor for CLocalVariable. @@ -35,15 +44,32 @@ public class CLocalVariable extends CDebugElement public CLocalVariable( CStackFrame stackFrame, ICVariable cdiVariable ) { super( (CDebugTarget)stackFrame.getDebugTarget() ); + fStackFrame = stackFrame; fCDIVariable = cdiVariable; } /* (non-Javadoc) - * @see org.eclipse.debug.core.model.IVariable#getValue() + * @see org.eclipse.cdt.debug.internal.core.CModificationVariable#setValue(ICValue) */ - public IValue getValue() throws DebugException + protected void setValue( ICValue value ) throws DebugException { - return null; + try + { + getCDIVariable().setValue( value ); + } + catch( CDIException e ) + { + targetRequestFailed( MessageFormat.format( "{0} occured modifying local variable value.", new String[] { e.toString() } ), e ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.core.CVariable#retrieveValue() + */ + protected ICValue retrieveValue() throws DebugException, CDIException + { + return ( getStackFrame().isSuspended() ) ? + getCDIVariable().getValue() : getLastKnownValue(); } /* (non-Javadoc) @@ -51,7 +77,16 @@ public class CLocalVariable extends CDebugElement */ public String getName() throws DebugException { - return null; + String name = null; + try + { + name = getCDIVariable().getName(); + } + catch( CDIException e ) + { + targetRequestFailed( MessageFormat.format( "{0} occured while retrieving local variable name.", new String[] { e.toString() } ), e ); + } + return name; } /* (non-Javadoc) @@ -59,65 +94,20 @@ public class CLocalVariable extends CDebugElement */ public String getReferenceTypeName() throws DebugException { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.model.IVariable#hasValueChanged() - */ - public boolean hasValueChanged() throws DebugException - { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.cdi.event.ICEventListener#handleDebugEvent(ICEvent) - */ - public void handleDebugEvent( ICEvent event ) - { - } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.model.IValueModification#setValue(String) - */ - public void setValue( String expression ) throws DebugException - { - } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.model.IValueModification#setValue(IValue) - */ - public void setValue( IValue value ) throws DebugException - { - } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.model.IValueModification#supportsValueModification() - */ - public boolean supportsValueModification() - { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.model.IValueModification#verifyValue(String) - */ - public boolean verifyValue( String expression ) throws DebugException - { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.model.IValueModification#verifyValue(IValue) - */ - public boolean verifyValue( IValue value ) throws DebugException - { - return false; + String type = null; + try + { + type = getCDIVariable().getTypeName(); + } + catch( CDIException e ) + { + targetRequestFailed( MessageFormat.format( "{0} occured while retrieving local variable type.", new String[] { e.toString() } ), e ); + } + return type; } /** - * Returns the underlying CDI variable that this model object is - * a proxy to. + * Returns the underlying CDI variable. * * @return the underlying CDI variable */ @@ -125,4 +115,56 @@ public class CLocalVariable extends CDebugElement { return fCDIVariable; } + + /** + * Returns the stack frame this variable is contained in. + * + * @return the stack frame + */ + protected CStackFrame getStackFrame() + { + return fStackFrame; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.cdi.event.ICEventListener#handleDebugEvent(ICEvent) + */ + public void handleDebugEvent( ICEvent event ) + { + ICObject source = event.getSource(); + if ( source.getCDITarget().equals( getCDITarget() ) ) + { + if ( event instanceof ICChangedEvent ) + { + if ( source instanceof ICVariable && source.equals( getCDIVariable() ) ) + { + handleChangedEvent( (ICChangedEvent)event ); + } + } + } + } + + private void handleChangedEvent( ICChangedEvent event ) + { + try + { + setValue( getCurrentValue() ); + fireChangeEvent( DebugEvent.CONTENT ); + } + catch( DebugException e ) + { + logError( e ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#setValue(IValue) + */ + public void setValue( IValue value ) throws DebugException + { + if ( verifyValue( value ) ) + { + setValue( ((CValue)value).getUnderlyingValue() ); + } + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CModificationVariable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CModificationVariable.java new file mode 100644 index 00000000000..09630605ed2 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CModificationVariable.java @@ -0,0 +1,121 @@ +/* + *(c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ + +package org.eclipse.cdt.debug.internal.core; + +import java.text.MessageFormat; + +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.model.ICArrayValue; +import org.eclipse.cdt.debug.core.cdi.model.ICExpression; +import org.eclipse.cdt.debug.core.cdi.model.ICStringValue; +import org.eclipse.cdt.debug.core.cdi.model.ICStructureValue; +import org.eclipse.cdt.debug.core.cdi.model.ICValue; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IValue; + +/** + * + * Common functionality for variables that support value modification + * + * @since Aug 9, 2002 + */ +public abstract class CModificationVariable extends CVariable +{ + private static final String ERROR_MESSAGE = "Value modification failed - unable to generate value from expression: {0}"; + + /** + * Constructor for CModificationVariable. + * @param target + */ + public CModificationVariable( CDebugTarget target ) + { + super( target ); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#supportsValueModification() + */ + public boolean supportsValueModification() + { + try + { + ICValue currentValue = getCurrentValue(); + if ( currentValue != null ) + { + return !( currentValue instanceof ICArrayValue || + currentValue instanceof ICStructureValue || + currentValue instanceof ICStringValue ); + } + } + catch( DebugException e ) + { + logError( e ); + } + return false; + } + + /** + * @see IValueModification#verifyValue(String) + */ + public boolean verifyValue( String expression ) + { + try + { + ICValue vmValue = generateValue( expression ); + return vmValue != null; + } + catch( DebugException e ) + { + logError( e ); + return false; + } + } + + protected ICValue generateValue( String expression ) throws DebugException + { + ICValue value = null; + try + { + value = getCDITarget().evaluateExpressionToValue( expression ); + } + catch( CDIException e ) + { + targetRequestFailed( MessageFormat.format( ERROR_MESSAGE, new String[] { expression } ), null ); + } + return value; + } + + /** + * @see IValueModification#verifyValue(IValue) + */ + public boolean verifyValue( IValue value ) + { + return value.getDebugTarget().equals( getDebugTarget() ); + } + + /** + * @see IValueModification#setValue(String) + */ + public final void setValue( String expression ) throws DebugException + { + ICValue value = generateValue( expression ); + + if ( value == null ) + { + targetRequestFailed( MessageFormat.format( ERROR_MESSAGE, new String[] { expression } ), null ); + } + + setValue( value ); + fireChangeEvent( DebugEvent.CONTENT ); + } + + /** + * Set this variable's value to the given value + */ + protected abstract void setValue( ICValue value ) throws DebugException; +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CStackFrame.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CStackFrame.java index 26941ba6853..8e91a8a7435 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CStackFrame.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CStackFrame.java @@ -254,8 +254,8 @@ public class CStackFrame extends CDebugElement catch( DebugException e ) { logError( e ); - return false; } + return false; } /* (non-Javadoc) @@ -299,9 +299,8 @@ public class CStackFrame extends CDebugElement { if ( !canStepInto() ) { - return; + getThread().stepInto(); } - getThread().stepInto(); } /* (non-Javadoc) @@ -504,6 +503,7 @@ public class CStackFrame extends CDebugElement protected void dispose() { getCDISession().getEventManager().removeEventListener( this ); + disposeAllVariables(); } /** @@ -557,4 +557,13 @@ public class CStackFrame extends CDebugElement IStackFrame tos = getThread().getTopStackFrame(); return tos != null && tos.equals( this ); } + + protected void disposeAllVariables() + { + Iterator it = fVariables.iterator(); + while( it.hasNext() ) + { + ((CVariable)it.next()).dispose(); + } + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CValue.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CValue.java new file mode 100644 index 00000000000..c4aa79de478 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CValue.java @@ -0,0 +1,93 @@ +/* + *(c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ + +package org.eclipse.cdt.debug.internal.core; + +import org.eclipse.cdt.debug.core.cdi.model.ICValue; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; + +/** + * + * The value of a variable. + * + * @since Aug 9, 2002 + */ +public class CValue extends CDebugElement implements IValue +{ + /** + * Underlying CDI value. + */ + private ICValue fValue; + + /** + * Constructor for CValue. + * @param target + */ + public CValue( CDebugTarget target, ICValue cdiValue ) + { + super( target ); + fValue = cdiValue; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValue#getReferenceTypeName() + */ + public String getReferenceTypeName() throws DebugException + { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValue#getValueString() + */ + public String getValueString() throws DebugException + { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValue#isAllocated() + */ + public boolean isAllocated() throws DebugException + { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValue#getVariables() + */ + public IVariable[] getVariables() throws DebugException + { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValue#hasVariables() + */ + public boolean hasVariables() throws DebugException + { + return false; + } + + /** + * Creates the appropriate kind of value, or null. + * + */ + public static CValue createValue( CDebugTarget target, ICValue value ) + { + return new CValue( target, value ); + } + + /** + * Returns this value's underlying CDI value + */ + protected ICValue getUnderlyingValue() + { + return fValue; + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CVariable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CVariable.java new file mode 100644 index 00000000000..96b5bf2103c --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CVariable.java @@ -0,0 +1,212 @@ +/* + *(c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ +package org.eclipse.cdt.debug.internal.core; + +import java.text.MessageFormat; + +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.event.ICEventListener; +import org.eclipse.cdt.debug.core.cdi.model.ICValue; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; + +/** + * + * A superclass for all variable classes. + * + * @since Aug 9, 2002 + */ +public abstract class CVariable extends CDebugElement + implements IVariable, + ICEventListener +{ + /** + * Cache of current value - see #getValue(). + */ + private CValue fValue; + + /** + * Counter corresponding to this variable's debug target + * suspend count indicating the last time this value + * changed. This variable's value has changed on the + * last suspend event if this counter is equal to the + * debug target's suspend count. + */ + private int fLastChangeIndex = -1; + + /** + * Constructor for CVariable. + * @param target + */ + public CVariable( CDebugTarget target ) + { + super( target ); + getCDISession().getEventManager().addEventListener( this ); + } + + /** + * Returns the current value of this variable. The value + * is cached, but on each access we see if the value has changed + * and update if required. + * + * @see org.eclipse.debug.core.model.IVariable#getValue() + */ + public IValue getValue() throws DebugException + { + ICValue currentValue = getCurrentValue(); + if ( fValue == null ) + { + fValue = CValue.createValue( (CDebugTarget)getDebugTarget(), currentValue ); + } + else + { + ICValue previousValue = fValue.getUnderlyingValue(); + if ( currentValue == previousValue ) + { + return fValue; + } + if ( previousValue == null || currentValue == null ) + { + fValue = CValue.createValue( (CDebugTarget)getDebugTarget(), currentValue ); + setChangeCount( ((CDebugTarget)getDebugTarget()).getSuspendCount()); + } + else if ( !previousValue.equals( currentValue ) ) + { + fValue = CValue.createValue( (CDebugTarget)getDebugTarget(), currentValue ); + setChangeCount( ((CDebugTarget)getDebugTarget()).getSuspendCount()); + } + } + return fValue; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IVariable#hasValueChanged() + */ + public boolean hasValueChanged() throws DebugException + { + return getChangeCount() == ((CDebugTarget)getDebugTarget()).getSuspendCount(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#setValue(String) + */ + public void setValue( String expression ) throws DebugException + { + notSupported( "Variable does not support value modification." ); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#setValue(IValue) + */ + public void setValue( IValue value ) throws DebugException + { + notSupported( "Variable does not support value modification." ); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#supportsValueModification() + */ + public boolean supportsValueModification() + { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#verifyValue(String) + */ + public boolean verifyValue( String expression ) throws DebugException + { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#verifyValue(IValue) + */ + public boolean verifyValue( IValue value ) throws DebugException + { + return false; + } + + /** + * Returns this variable's underlying CDI value. + */ + protected abstract ICValue retrieveValue() throws DebugException, CDIException; + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class) + */ + public Object getAdapter( Class adapter ) + { + if ( adapter.equals( IVariable.class ) ) + return this; + return super.getAdapter( adapter ); + } + + /** + * Returns this variable's current underlying CDI value. + * Subclasses must implement #retrieveValue() and do not + * need to guard against CDIException, as this method + * handles them. + * + * @exception DebugException if unable to access the value + */ + protected final ICValue getCurrentValue() throws DebugException + { + try + { + return retrieveValue(); + } + catch( CDIException e ) + { + targetRequestFailed( MessageFormat.format( "{0} occurred retrieving value.", new String[] { e.toString() } ), e ); + // execution will not reach this line, as + // #targetRequestFailed will throw an exception + return null; + } + } + + /** + * Sets this variable's change counter to the specified value + * + * @param count new value + */ + protected void setChangeCount( int count ) + { + fLastChangeIndex = count; + } + + /** + * Returns this variable's change counter. This corresponds to the + * last time this variable changed. + * + * @return this variable's change counter + */ + protected int getChangeCount() + { + return fLastChangeIndex; + } + + /** + * Returns the last known value for this variable + */ + protected ICValue getLastKnownValue() + { + if ( fValue == null ) + { + return null; + } + else + { + return fValue.getUnderlyingValue(); + } + } + + protected void dispose() + { + getCDISession().getEventManager().removeEventListener( this ); + } +}