/*******************************************************************************
* Copyright (c) 2004, 2008 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.internal.core.model;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDIArgumentDescriptor;
import org.eclipse.cdt.debug.core.cdi.model.ICDILocalVariableDescriptor;
import org.eclipse.cdt.debug.core.cdi.model.ICDIObject;
import org.eclipse.cdt.debug.core.cdi.model.ICDITargetConfiguration2;
import org.eclipse.cdt.debug.core.cdi.model.ICDIValue;
import org.eclipse.cdt.debug.core.cdi.model.ICDIVariable;
import org.eclipse.cdt.debug.core.cdi.model.ICDIVariableDescriptor;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIArrayValue;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIType;
import org.eclipse.cdt.debug.core.model.ICType;
import org.eclipse.cdt.debug.core.model.ICValue;
import org.eclipse.debug.core.DebugException;
public class CLocalVariable extends CVariable {
private class InternalVariable implements IInternalVariable {
/**
* The enclosing <code>CVariable</code> instance.
*/
private CVariable fVariable;
/**
* The CDI variable object this variable is based on.
*/
private ICDIVariableDescriptor fCDIVariableObject;
/**
* The underlying CDI variable.
*/
private ICDIVariable fCDIVariable;
/**
* The type of this variable.
*/
private CType fType;
/**
* The expression used to eveluate the value of this variable.
*/
private String fQualifiedName;
/**
* The cache of the current value.
*/
private ICValue fValue = CValueFactory.NULL_VALUE;
/**
* The change flag.
*/
private boolean fChanged = false;
/**
* Constructor for InternalVariable.
*/
InternalVariable( CVariable var, ICDIVariableDescriptor varObject ) {
setVariable( var );
setCDIVariableObject( varObject );
setCDIVariable( (varObject instanceof ICDIVariable) ? (ICDIVariable)varObject : null );
}
public IInternalVariable createShadow( int start, int length ) throws DebugException {
IInternalVariable iv = null;
try {
iv = new InternalVariable( getVariable(), getCDIVariableObject().getVariableDescriptorAsArray( start, length ) );
}
catch( CDIException e ) {
requestFailed( e.getMessage(), null );
}
return iv;
}
public IInternalVariable createShadow( String type ) throws DebugException {
IInternalVariable iv = null;
try {
iv = new InternalVariable( getVariable(), getCDIVariableObject().getVariableDescriptorAsType( type ) );
}
catch( CDIException e ) {
requestFailed( e.getMessage(), null );
}
return iv;
}
private synchronized ICDIVariable getCDIVariable() throws DebugException {
if ( fCDIVariable == null ) {
try {
fCDIVariable = ((CStackFrame)getStackFrame()).getCDIStackFrame().createLocalVariable( (ICDILocalVariableDescriptor)getCDIVariableObject() );
}
catch( CDIException e ) {
requestFailed( e.getMessage(), null );
}
}
return fCDIVariable;
}
private void setCDIVariable( ICDIVariable variable ) {
fCDIVariable = variable;
}
private ICDIVariableDescriptor getCDIVariableObject() {
if ( fCDIVariable != null ) {
return fCDIVariable;
}
return fCDIVariableObject;
}
private void setCDIVariableObject( ICDIVariableDescriptor variableObject ) {
fCDIVariableObject = variableObject;
}
public String getQualifiedName() throws DebugException {
if ( fQualifiedName == null ) {
try {
fQualifiedName = (fCDIVariableObject != null) ? fCDIVariableObject.getQualifiedName() : null;
}
catch( CDIException e ) {
requestFailed( e.getMessage(), null );
}
}
return fQualifiedName;
}
public CType getType() throws DebugException {
if ( fType == null ) {
ICDIVariableDescriptor varObject = getCDIVariableObject();
if ( varObject != null ) {
synchronized( this ) {
if ( fType == null ) {
try {
fType = new CType( varObject.getType() );
}
catch( CDIException e ) {
requestFailed( e.getMessage(), null );
}
}
}
}
}
return fType;
}
private synchronized void invalidate( boolean destroy ) {
try {
if ( destroy && fCDIVariable != null )
fCDIVariable.dispose();
}
catch( CDIException e ) {
logError( e.getMessage() );
}
invalidateValue();
setCDIVariable( null );
if ( fType != null )
fType.dispose();
fType = null;
}
public void dispose( boolean destroy ) {
invalidate( destroy );
}
public boolean isSameVariable( ICDIVariable cdiVar ) {
return ( fCDIVariable != null ) ? fCDIVariable.equals( cdiVar ) : false;
}
public int sizeof() {
if ( getCDIVariableObject() != null ) {
try {
return getCDIVariableObject().sizeof();
}
catch( CDIException e ) {
}
}
return 0;
}
public boolean isArgument() {
return ( getCDIVariableObject() instanceof ICDIArgumentDescriptor );
}
public void setValue( String expression ) throws DebugException {
ICDIVariable cdiVariable = null;
try {
cdiVariable = getCDIVariable();
if ( cdiVariable != null )
cdiVariable.setValue( expression );
else
requestFailed( CoreModelMessages.getString( "CModificationVariable.0" ), null ); //$NON-NLS-1$
}
catch( CDIException e ) {
targetRequestFailed( e.getMessage(), null );
}
}
public synchronized ICValue getValue() throws DebugException {
if ( fValue.equals( CValueFactory.NULL_VALUE ) ) {
ICDIVariable var = getCDIVariable();
if ( var != null ) {
try {
ICDIValue cdiValue = var.getValue();
if ( cdiValue != null ) {
ICDIType cdiType = cdiValue.getType();
if ( cdiValue instanceof ICDIArrayValue && cdiType != null ) {
ICType type = new CType( cdiType );
if ( type.isArray() ) {
int[] dims = type.getArrayDimensions();
if ( dims.length > 0 && dims[0] > 0 )
fValue = CValueFactory.createIndexedValue( getVariable(), (ICDIArrayValue)cdiValue, 0, dims[0] );
}
}
else {
fValue = CValueFactory.createValue( getVariable(), cdiValue );
}
}
if (getCDITarget().getConfiguration() instanceof ICDITargetConfiguration2 &&
((ICDITargetConfiguration2)getCDITarget().getConfiguration()).supportsRuntimeTypeIdentification())
fType = null; // When the debugger supports RTTI getting a new value may also mean a new type.
}
catch( CDIException e ) {
requestFailed( e.getMessage(), e );
}
}
}
return fValue;
}
public void invalidateValue() {
if ( fValue instanceof AbstractCValue ) {
((AbstractCValue)fValue).dispose();
fValue = CValueFactory.NULL_VALUE;
}
}
public boolean isChanged() {
return fChanged;
}
public synchronized void setChanged( boolean changed ) {
if ( changed ) {
invalidateValue();
}
if ( fValue instanceof AbstractCValue ) {
((AbstractCValue)fValue).setChanged( changed );
}
fChanged = changed;
}
public synchronized void preserve() {
setChanged( false );
if ( fValue instanceof AbstractCValue ) {
((AbstractCValue)fValue).preserve();
}
}
CVariable getVariable() {
return fVariable;
}
private void setVariable( CVariable variable ) {
fVariable = variable;
}
public void resetValue() {
if ( fValue instanceof AbstractCValue ) {
((AbstractCValue)fValue).reset();
}
}
public boolean isEditable() throws DebugException {
ICDIVariable var = getCDIVariable();
if ( var != null ) {
try {
return var.isEditable();
}
catch( CDIException e ) {
}
}
return false;
}
/**
* Compares the underlying variable objects.
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals( Object obj ) {
if ( obj instanceof InternalVariable ) {
return getCDIVariableObject().equals( ((InternalVariable)obj).getCDIVariableObject() );
}
return false;
}
public boolean isSameDescriptor( ICDIVariableDescriptor desc ) {
return getCDIVariableObject().equals( desc );
}
public ICDIObject getCdiObject() {
return fCDIVariable;
}
}
/**
* Constructor for CLocalVariable.
*/
public CLocalVariable( CDebugElement parent, ICDIVariableDescriptor cdiVariableObject, String errorMessage ) {
super( parent, cdiVariableObject, errorMessage );
}
/**
* Constructor for CLocalVariable.
*/
public CLocalVariable( CDebugElement parent, ICDIVariableDescriptor cdiVariableObject ) {
super( parent, cdiVariableObject );
}
protected void createOriginal( ICDIVariableDescriptor vo ) {
if ( vo != null ) {
setName( vo.getName() );
setOriginal( new InternalVariable( this, vo ) );
}
}
}