mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-04 15:45:25 +02:00
Merge remote-tracking branch 'cdt/master' into sd90
This commit is contained in:
commit
b410a5b97d
10 changed files with 751 additions and 101 deletions
|
@ -291,8 +291,8 @@ public class CConventions {
|
|||
if (!isValidIdentifier(id)) {
|
||||
return new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, NLS.bind(Messages.convention_invalid, id), null);
|
||||
}
|
||||
|
||||
if (isReservedKeyword(id, language)) {
|
||||
|
||||
if (isReservedKeyword(id, language) || isBuiltinType(id, language)) {
|
||||
return new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, NLS.bind(Messages.convention_reservedKeyword, id), null);
|
||||
}
|
||||
|
||||
|
@ -369,7 +369,16 @@ public class CConventions {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static boolean isBuiltinType(String name, AbstractCLikeLanguage language) {
|
||||
String[] types = language.getBuiltinTypes();
|
||||
for (String type : types) {
|
||||
if (type.equals(name))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isLegalFilename(String name) {
|
||||
if (name == null || name.isEmpty()) {
|
||||
return false;
|
||||
|
|
BIN
debug/org.eclipse.cdt.debug.ui/icons/obj16/arraypartition_obj.gif
Executable file
BIN
debug/org.eclipse.cdt.debug.ui/icons/obj16/arraypartition_obj.gif
Executable file
Binary file not shown.
After Width: | Height: | Size: 370 B |
|
@ -104,6 +104,7 @@ public class CDebugImages {
|
|||
public static final String IMG_OBJS_PATH_MAPPING = NAME_PREFIX + "mapping_obj.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_OBJS_PATH_MAP_ENTRY = NAME_PREFIX + "mapentry_obj.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_OBJS_COMMON_TAB = NAME_PREFIX + "common_tab.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_OBJS_ARRAY_PARTITION = NAME_PREFIX + "arraypartition_obj.gif"; //$NON-NLS-1$
|
||||
|
||||
public static final String IMG_LCL_TYPE_NAMES = NAME_PREFIX + "tnames_co.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_LCL_CHANGE_REGISTER_VALUE = NAME_PREFIX + "change_reg_value_co.gif"; //$NON-NLS-1$
|
||||
|
@ -188,6 +189,7 @@ public class CDebugImages {
|
|||
public static final ImageDescriptor DESC_OBJS_PATH_MAPPING = createManaged(T_OBJ, IMG_OBJS_PATH_MAPPING);
|
||||
public static final ImageDescriptor DESC_OBJS_PATH_MAP_ENTRY = createManaged(T_OBJ, IMG_OBJS_PATH_MAP_ENTRY);
|
||||
public static final ImageDescriptor DESC_OBJS_COMMON_TAB = createManaged(T_OBJ, IMG_OBJS_COMMON_TAB);
|
||||
public static final ImageDescriptor DESC_OBJS_ARRAY_PARTITION = createManaged(T_OBJ, IMG_OBJS_ARRAY_PARTITION);
|
||||
public static final ImageDescriptor DESC_WIZBAN_ADD_SOURCE = createManaged(T_WIZBAN, IMG_WIZBAN_ADD_SOURCE);
|
||||
public static final ImageDescriptor DESC_WIZBAN_PATH_MAPPING = createManaged(T_WIZBAN, IMG_WIZBAN_PATH_MAPPING);
|
||||
public static final ImageDescriptor DESC_WIZBAN_PATH_MAP_ENTRY = createManaged(T_WIZBAN, IMG_WIZBAN_PATH_MAP_ENTRY);
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.IAddress;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
|
||||
|
@ -71,6 +73,8 @@ import org.osgi.framework.BundleContext;
|
|||
*/
|
||||
public class MIExpressions extends AbstractDsfService implements IMIExpressions, ICachingService {
|
||||
|
||||
private static final int PARTITION_LENGTH = 100;
|
||||
|
||||
/**
|
||||
* A format that gives more details about an expression and supports pretty-printing
|
||||
* provided by the backend.
|
||||
|
@ -381,7 +385,7 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
|
|||
this.exprInfo = info;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class InvalidContextExpressionDMC extends AbstractDMContext
|
||||
implements IExpressionDMContext
|
||||
{
|
||||
|
@ -413,6 +417,86 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
|
|||
return expression;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
protected static class IndexedPartitionDMC extends MIExpressionDMC implements IIndexedPartitionDMContext {
|
||||
|
||||
final private ExpressionInfo fParentInfo;
|
||||
private final int fIndex;
|
||||
private final int fLength;
|
||||
|
||||
public IndexedPartitionDMC(
|
||||
String sessionId,
|
||||
ExpressionInfo parentInfo,
|
||||
IFrameDMContext frameCtx,
|
||||
int index,
|
||||
int length) {
|
||||
this(sessionId, parentInfo, (IDMContext)frameCtx, index, length);
|
||||
}
|
||||
|
||||
private IndexedPartitionDMC(
|
||||
String sessionId,
|
||||
ExpressionInfo parentInfo,
|
||||
IDMContext parent,
|
||||
int index,
|
||||
int length) {
|
||||
super(sessionId, createExpressionInfo(parentInfo, index, length), parent);
|
||||
fIndex = index;
|
||||
fLength = length;
|
||||
fParentInfo = parentInfo;
|
||||
}
|
||||
|
||||
public ExpressionInfo getParentInfo() {
|
||||
return fParentInfo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.debug.service.IExpressions4.IIndexedPartitionDMContext#getParentExpression()
|
||||
*/
|
||||
@Override
|
||||
public String getParentExpression() {
|
||||
return getParentInfo().getFullExpr();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return fIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return fLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return super.baseEquals(other) &&
|
||||
((IndexedPartitionDMC) other).getParentInfo().equals(getParentInfo()) &&
|
||||
((IndexedPartitionDMC) other).getIndex() == getIndex() &&
|
||||
((IndexedPartitionDMC) other).getLength() == getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.baseHashCode() + 17*getIndex() + 31*getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format( "%s.expr[%s][%d-%d]", baseToString(), getParentExpression(), getIndex(), getIndex() + getLength() - 1); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private static ExpressionInfo createExpressionInfo(ExpressionInfo parentInfo, int index, int length) {
|
||||
String expression = String.format(
|
||||
"*((%s)+%d)@%d", //$NON-NLS-1$
|
||||
parentInfo.getFullExpr(),
|
||||
Integer.valueOf(index),
|
||||
Integer.valueOf(length));
|
||||
return new ExpressionInfo(expression, expression);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1064,33 +1148,8 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
|
|||
* The data request monitor that will contain the requested data
|
||||
*/
|
||||
@Override
|
||||
public void getSubExpressions(final IExpressionDMContext dmc,
|
||||
final DataRequestMonitor<IExpressionDMContext[]> rm)
|
||||
{
|
||||
if (dmc instanceof MIExpressionDMC) {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetChildren(dmc),
|
||||
new DataRequestMonitor<ExprMetaGetChildrenInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
ExpressionInfo[] childrenExpr = getData().getChildrenExpressions();
|
||||
IExpressionDMContext[] childArray = new IExpressionDMContext[childrenExpr.length];
|
||||
for (int i=0; i<childArray.length; i++) {
|
||||
childArray[i] = createExpression(
|
||||
dmc.getParents()[0], childrenExpr[i]);
|
||||
}
|
||||
|
||||
rm.setData(childArray);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else if (dmc instanceof InvalidContextExpressionDMC) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid expression context.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
public void getSubExpressions(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMContext[]> rm) {
|
||||
getSubExpressions(dmc, -1, -1, rm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1112,37 +1171,48 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
|
|||
public void getSubExpressions(final IExpressionDMContext exprCtx, final int startIndex,
|
||||
final int length, final DataRequestMonitor<IExpressionDMContext[]> rm) {
|
||||
|
||||
if (startIndex < 0 || length < 0) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid range for evaluating sub expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
if (exprCtx instanceof IndexedPartitionDMC) {
|
||||
getIndexedPartitionChildren((IndexedPartitionDMC)exprCtx, startIndex, length, rm);
|
||||
}
|
||||
|
||||
if (exprCtx instanceof MIExpressionDMC) {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetChildren(exprCtx, startIndex + length),
|
||||
new DataRequestMonitor<ExprMetaGetChildrenInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
ExpressionInfo[] childrenExpr = getData().getChildrenExpressions();
|
||||
|
||||
if (startIndex >= childrenExpr.length) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, "Invalid range for evaluating sub expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
int numChildren = childrenExpr.length - startIndex;
|
||||
numChildren = Math.min(length, numChildren);
|
||||
IExpressionDMContext[] childrenArray = new IExpressionDMContext[numChildren];
|
||||
for (int i=0; i < numChildren; i++) {
|
||||
childrenArray[i] = createExpression(
|
||||
exprCtx.getParents()[0], childrenExpr[startIndex + i]);
|
||||
}
|
||||
rm.setData(childrenArray);
|
||||
else if (exprCtx instanceof MIExpressionDMC) {
|
||||
getRealSubExpressionCount(
|
||||
exprCtx,
|
||||
IMIExpressions.CHILD_COUNT_LIMIT_UNSPECIFIED,
|
||||
new DataRequestMonitor<Integer>(getExecutor(), rm) {
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.concurrent.RequestMonitor#handleSuccess()
|
||||
*/
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
final int realNumChildren = getData().intValue();
|
||||
if (realNumChildren == 0) {
|
||||
rm.setData(new IExpressionDMContext[0]);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (realNumChildren <= getArrayPartitionLength()) {
|
||||
getRealSubExpressions(exprCtx, startIndex, length, rm);
|
||||
}
|
||||
else {
|
||||
getExpressionData(
|
||||
exprCtx,
|
||||
new DataRequestMonitor<IExpressionDMData>(ImmediateExecutor.getInstance(), rm) {
|
||||
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (IExpressionDMData.BasicType.array.equals(getData().getBasicType())) {
|
||||
rm.setData(getTopLevelIndexedPartitions((MIExpressionDMC)exprCtx, realNumChildren, startIndex, length ));
|
||||
rm.done();
|
||||
}
|
||||
else {
|
||||
getRealSubExpressions(exprCtx, startIndex, length, rm);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (exprCtx instanceof InvalidContextExpressionDMC) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
|
@ -1183,19 +1253,48 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
|
|||
* @since 4.0
|
||||
*/
|
||||
@Override
|
||||
public void getSubExpressionCount(IExpressionDMContext dmc,
|
||||
public void getSubExpressionCount(final IExpressionDMContext dmc,
|
||||
final int numChildLimit, final DataRequestMonitor<Integer> rm) {
|
||||
|
||||
if (dmc instanceof MIExpressionDMC) {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetChildCount(dmc, numChildLimit),
|
||||
new DataRequestMonitor<ExprMetaGetChildCountInfo>(getExecutor(), rm) {
|
||||
if (dmc instanceof IndexedPartitionDMC) {
|
||||
int length = ((IndexedPartitionDMC)dmc).getLength();
|
||||
rm.setData(computeNumberOfChildren(length));
|
||||
rm.done();
|
||||
}
|
||||
else {
|
||||
getRealSubExpressionCount(
|
||||
dmc,
|
||||
numChildLimit,
|
||||
new DataRequestMonitor<Integer>(getExecutor(), rm) {
|
||||
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(getData().getChildNum());
|
||||
rm.done();
|
||||
}
|
||||
final int realNum = getData().intValue();
|
||||
if (realNum <= getArrayPartitionLength()) {
|
||||
rm.setData(Integer.valueOf(realNum));
|
||||
rm.done();
|
||||
}
|
||||
else {
|
||||
getExpressionData(
|
||||
dmc,
|
||||
new DataRequestMonitor<IExpressionDMData>(ImmediateExecutor.getInstance(), rm) {
|
||||
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (IExpressionDMData.BasicType.array.equals(getData().getBasicType())) {
|
||||
rm.setData(computeNumberOfChildren(realNum));
|
||||
}
|
||||
else {
|
||||
rm.setData(Integer.valueOf(realNum));
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (dmc instanceof InvalidContextExpressionDMC) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
|
@ -1442,4 +1541,196 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
private IndexedPartitionDMC[] getTopLevelIndexedPartitions(
|
||||
MIExpressionDMC exprCtx,
|
||||
int realNumChildren,
|
||||
int startIndex,
|
||||
int length) {
|
||||
|
||||
int numChildren = computeNumberOfChildren(realNumChildren);
|
||||
if (startIndex >= numChildren)
|
||||
return new IndexedPartitionDMC[0];
|
||||
int startIndex1 = (startIndex < 0) ? 0 : startIndex;
|
||||
int length1 = (length < 0) ? numChildren - startIndex1 : Math.min(length, numChildren - startIndex1);
|
||||
|
||||
IndexedPartitionDMC[] children = new IndexedPartitionDMC[numChildren];
|
||||
int index = 0;
|
||||
for(int i = 0; i < children.length; ++i) {
|
||||
int partLength = computePartitionLength(realNumChildren, i);
|
||||
children[i] = createIndexedPartition(
|
||||
exprCtx.getParents()[0],
|
||||
exprCtx.getExpressionInfo(),
|
||||
index,
|
||||
partLength);
|
||||
index += partLength;
|
||||
}
|
||||
return Arrays.copyOfRange(children, startIndex1, startIndex1 + length1 );
|
||||
}
|
||||
|
||||
private void getIndexedPartitionChildren(
|
||||
final IndexedPartitionDMC partDmc,
|
||||
final int startIndex,
|
||||
final int length,
|
||||
final DataRequestMonitor<IExpressionDMContext[]> rm) {
|
||||
|
||||
final int startIndex1 = (startIndex < 0) ? 0 : startIndex;
|
||||
final int length1 = (length < 0) ? Integer.MAX_VALUE : length;
|
||||
|
||||
final int partStartIndex = partDmc.getIndex();
|
||||
final int partLength = partDmc.getLength();
|
||||
if (partLength > getArrayPartitionLength()) {
|
||||
// create subpartitions
|
||||
int numChildren = computeNumberOfChildren(partLength);
|
||||
|
||||
if (startIndex1 >= numChildren) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, "Invalid range for evaluating sub expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
int numPart = Math.min(numChildren, length1);
|
||||
IndexedPartitionDMC[] children = new IndexedPartitionDMC[numPart];
|
||||
int index = partStartIndex;
|
||||
for (int i = 0; i < startIndex1; ++i)
|
||||
index += computePartitionLength(partLength, i);
|
||||
for (int i = 0; i < children.length; ++i) {
|
||||
int childPartLength = computePartitionLength(partLength, i + startIndex1);
|
||||
children[i] = createIndexedPartition(
|
||||
partDmc,
|
||||
partDmc.getParentInfo(),
|
||||
index,
|
||||
childPartLength);
|
||||
index += childPartLength;
|
||||
}
|
||||
rm.setData(children);
|
||||
rm.done();
|
||||
}
|
||||
else {
|
||||
// this is the last partition level, create "real" children
|
||||
if (startIndex1 > partLength) {
|
||||
rm.setData(new IExpressionDMContext[0]);
|
||||
rm.done();
|
||||
}
|
||||
else {
|
||||
getRealSubExpressions(
|
||||
createExpression(partDmc.getParents()[0], partDmc.getParentInfo()),
|
||||
partStartIndex + startIndex1,
|
||||
Math.min(length1, partLength - startIndex1),
|
||||
rm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getRealSubExpressions(
|
||||
final IExpressionDMContext exprCtx,
|
||||
int startIndex,
|
||||
int length,
|
||||
final DataRequestMonitor<IExpressionDMContext[]> rm) {
|
||||
|
||||
ExprMetaGetChildren getChildren = (startIndex < 0 || length < 0) ?
|
||||
new ExprMetaGetChildren(exprCtx) : new ExprMetaGetChildren(exprCtx, startIndex + length);
|
||||
final int startIndex1 = (startIndex < 0) ? 0 : startIndex;
|
||||
final int length1 = (length < 0) ? Integer.MAX_VALUE : length;
|
||||
fExpressionCache.execute(
|
||||
getChildren,
|
||||
new DataRequestMonitor<ExprMetaGetChildrenInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
ExpressionInfo[] childrenExpr = getData().getChildrenExpressions();
|
||||
|
||||
if (startIndex1 >= childrenExpr.length) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, "Invalid range for evaluating sub expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
int numChildren = childrenExpr.length - startIndex1;
|
||||
numChildren = Math.min(length1, numChildren);
|
||||
IExpressionDMContext[] childrenArray = new IExpressionDMContext[numChildren];
|
||||
for (int i=0; i < numChildren; i++) {
|
||||
childrenArray[i] = createExpression(exprCtx.getParents()[0], childrenExpr[startIndex1 + i]);
|
||||
}
|
||||
rm.setData(childrenArray);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of "real" children if it is less or equal to the partition size,
|
||||
* otherwise returns the number of partitions.
|
||||
*/
|
||||
private int computeNumberOfChildren(int realNumberOfChildren) {
|
||||
int childNum = realNumberOfChildren;
|
||||
int partLength = getArrayPartitionLength();
|
||||
while (childNum > partLength) {
|
||||
childNum /= partLength;
|
||||
}
|
||||
if (childNum*partLength < realNumberOfChildren)
|
||||
++childNum;
|
||||
return childNum;
|
||||
}
|
||||
|
||||
private int computePartitionLength(int realNumberOfChildren, int index) {
|
||||
int childNum = realNumberOfChildren;
|
||||
int depth = 0;
|
||||
int partLength = getArrayPartitionLength();
|
||||
int length = partLength;
|
||||
while (childNum > partLength) {
|
||||
childNum /= partLength;
|
||||
if (depth > 0)
|
||||
length *= partLength;
|
||||
++depth;
|
||||
}
|
||||
int diff = realNumberOfChildren - length*index;
|
||||
return ( diff > length ) ? length : diff ;
|
||||
}
|
||||
|
||||
private IndexedPartitionDMC createIndexedPartition(IDMContext ctx, ExpressionInfo info, int index, int length) {
|
||||
IFrameDMContext frameDmc = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
|
||||
if (frameDmc != null) {
|
||||
return new IndexedPartitionDMC(getSession().getId(), info, frameDmc, index, length);
|
||||
}
|
||||
|
||||
IMIExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class);
|
||||
if (execCtx != null) {
|
||||
// If we have a thread context but not a frame context, we give the user
|
||||
// the expression as per the top-most frame of the specified thread.
|
||||
// To do this, we create our own frame context.
|
||||
MIStack stackService = getServicesTracker().getService(MIStack.class);
|
||||
if (stackService != null) {
|
||||
frameDmc = stackService.createFrameDMContext(execCtx, 0);
|
||||
return new IndexedPartitionDMC(getSession().getId(), info, frameDmc, index, length);
|
||||
}
|
||||
}
|
||||
|
||||
return new IndexedPartitionDMC(getSession().getId(), info, ctx, index, length);
|
||||
}
|
||||
|
||||
private void getRealSubExpressionCount(IExpressionDMContext dmc, int numChildLimit, final DataRequestMonitor<Integer> rm) {
|
||||
if (dmc instanceof MIExpressionDMC) {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetChildCount(dmc, numChildLimit),
|
||||
new DataRequestMonitor<ExprMetaGetChildCountInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(getData().getChildNum());
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else if (dmc instanceof InvalidContextExpressionDMC) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid expression context.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
private int getArrayPartitionLength() {
|
||||
// Replace this in case we or the platform decide to add a user preference.
|
||||
// See org.eclipse.debug.internal.ui.model.elements.VariableContentProvider.
|
||||
return PARTITION_LENGTH;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
|||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IIndexedPartitionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions2.ICastedExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
|
||||
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
||||
|
@ -1274,6 +1275,9 @@ public class MIVariableManager implements ICommandControl {
|
|||
exprName = '(' + exprName + ')';
|
||||
castingIndex = ((ICastedExpressionDMContext)exprDmc).getCastInfo().getArrayStartIndex();
|
||||
}
|
||||
if (exprDmc instanceof IIndexedPartitionDMContext) {
|
||||
castingIndex = ((IIndexedPartitionDMContext)exprDmc).getIndex();
|
||||
}
|
||||
for (int i= 0; i < childrenOfArray.length; i++) {
|
||||
String fullExpr = exprName + "[" + i + "]";//$NON-NLS-1$//$NON-NLS-2$
|
||||
String relExpr = exprDmc.getRelativeExpression() + "[" + (castingIndex + i) + "]";//$NON-NLS-1$//$NON-NLS-2$
|
||||
|
|
|
@ -293,6 +293,16 @@ int testCanWrite() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int testArrays() {
|
||||
int array_simple[10];
|
||||
int array_int[24321];
|
||||
foo array_foo[1200];
|
||||
int array_double_small[11][21];
|
||||
char array_double_large[111][210];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("Running ExpressionTest App\n");
|
||||
|
||||
|
@ -317,6 +327,7 @@ int main() {
|
|||
testConcurrentUpdateOutOfScopeChildThenParent();
|
||||
testUpdateOfPointer();
|
||||
testCanWrite();
|
||||
testArrays();
|
||||
|
||||
// For bug 320277
|
||||
BaseTest b; b.test();
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent;
|
|||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMData;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IIndexedPartitionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions3.IExpressionDMDataExtension;
|
||||
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
|
||||
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
||||
|
@ -320,37 +321,10 @@ public class MIExpressionsTest extends BaseTestCase {
|
|||
|
||||
final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
|
||||
|
||||
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
|
||||
|
||||
// First we get the expected value of the array pointer.
|
||||
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, "f");
|
||||
|
||||
fExpService.getExecutor().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fExpService.getSubExpressionCount(
|
||||
exprDmc,
|
||||
new DataRequestMonitor<Integer>(fExpService.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
wait.waitFinished(getStatus());
|
||||
} else {
|
||||
int count = getData();
|
||||
if (count != 5) {
|
||||
wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID,
|
||||
"Failed getting count for children. Got " + count + " instead of 5", null));
|
||||
} else {
|
||||
wait.waitFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertTrue(wait.getMessage(), wait.isOK());
|
||||
getChildrenCount(exprDmc, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3263,6 +3237,7 @@ public class MIExpressionsTest extends BaseTestCase {
|
|||
getExprChangedCount() == 0);
|
||||
}
|
||||
|
||||
// This method tests IExspressions.getSubExpressions(IExpressionDMC, DRM);
|
||||
private IExpressionDMContext[] getChildren(
|
||||
final IExpressionDMContext parentDmc,
|
||||
String[] expectedValues) throws Throwable {
|
||||
|
@ -3311,4 +3286,287 @@ public class MIExpressionsTest extends BaseTestCase {
|
|||
|
||||
return childDmcs;
|
||||
}
|
||||
|
||||
// This method tests IExpressions.getSubExpressions(IExpressionDMC, int, int, DRM);
|
||||
private IExpressionDMContext[] getChildren(
|
||||
final IExpressionDMContext parentDmc,
|
||||
final int startIndex,
|
||||
final int length,
|
||||
String[] expectedValues) throws Throwable {
|
||||
|
||||
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
|
||||
|
||||
fExpService.getExecutor().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
fExpService.getSubExpressions(
|
||||
parentDmc,
|
||||
startIndex,
|
||||
length,
|
||||
new DataRequestMonitor<IExpressionDMContext[]>(fExpService.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
wait.setReturnInfo(getData());
|
||||
}
|
||||
wait.waitFinished(getStatus());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertTrue(wait.getMessage(), wait.isOK());
|
||||
|
||||
IExpressionDMContext[] childDmcs =
|
||||
(IExpressionDMContext[]) wait.getReturnInfo();
|
||||
|
||||
String[] childExpressions = new String[childDmcs.length];
|
||||
MIExpressionDMCAccessor[] childDmcsAccessor = new MIExpressionDMCAccessor[childDmcs.length];
|
||||
|
||||
// Convert to a MIExpressionDMCAccessor to be able to call getRelativeExpression
|
||||
// Also convert to String[] to be able to use Arrays.toString()
|
||||
for (int i = 0; i < childExpressions.length; i++) {
|
||||
childDmcsAccessor[i] = new MIExpressionDMCAccessor(childDmcs[i]);
|
||||
childExpressions[i] = childDmcsAccessor[i].getRelativeExpression();
|
||||
}
|
||||
assertTrue("Expected " + Arrays.toString(expectedValues) + " but got " + Arrays.toString(childExpressions),
|
||||
expectedValues.length == childExpressions.length);
|
||||
|
||||
for (int i = 0; i < childDmcsAccessor.length; i++) {
|
||||
assertTrue("Expected: " + expectedValues[i] + " got: " + childDmcsAccessor[i].getRelativeExpression(),
|
||||
childDmcsAccessor[i].getRelativeExpression().equals(expectedValues[i]));
|
||||
}
|
||||
|
||||
return childDmcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* This test verifies that large arrays are properly partitioned and
|
||||
* the handling of "small" arrays is not affected.
|
||||
*/
|
||||
@Test
|
||||
public void testArrays() throws Throwable {
|
||||
MIStoppedEvent stoppedEvent = SyncUtil.runToLocation("testArrays");
|
||||
|
||||
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
|
||||
|
||||
// int array_simple[10];
|
||||
IExpressionDMContext arraySimpleExprDMC = SyncUtil.createExpression(frameDmc, "array_simple");
|
||||
|
||||
getChildrenCount(arraySimpleExprDMC, 10);
|
||||
|
||||
// get all children
|
||||
String[] expectedValues = new String[10];
|
||||
for (int i = 0; i < expectedValues.length; ++i) {
|
||||
expectedValues[i] = String.format("array_simple[%d]", i);
|
||||
}
|
||||
IExpressionDMContext[] arraySimpleChildren = getChildren(arraySimpleExprDMC, expectedValues);
|
||||
for (IExpressionDMContext ctx : arraySimpleChildren)
|
||||
getChildren(ctx, new String[0]);
|
||||
|
||||
// get some parts of the children array
|
||||
getChildren(arraySimpleExprDMC, 3, 2, new String[] { "array_simple[3]", "array_simple[4]" });
|
||||
getChildren(arraySimpleExprDMC, 9, 3, new String[] { "array_simple[9]" });
|
||||
|
||||
// int array_int[24321];
|
||||
IExpressionDMContext arrayIntExprDMC = SyncUtil.createExpression(frameDmc, "array_int");
|
||||
getChildrenCount(arrayIntExprDMC, 3);
|
||||
|
||||
// get top level partitions: [0-9999], [10000-19999], [20000-24321]
|
||||
IExpressionDMContext[] arrayIntPartitions =
|
||||
getChildren(arrayIntExprDMC, new String[] {"*((array_int)+0)@10000", "*((array_int)+10000)@10000", "*((array_int)+20000)@4321"});
|
||||
assertTrue(String.format("Invalid number of partition: expected 3 got %d", arrayIntPartitions.length), arrayIntPartitions.length == 3);
|
||||
|
||||
// get children of the last partition: [20000-24321]
|
||||
expectedValues = new String[44];
|
||||
for(int i = 0; i < expectedValues.length - 1; ++i) {
|
||||
expectedValues[i] = String.format("*((array_int)+%d)@100", 20000 + i*100);
|
||||
}
|
||||
expectedValues[expectedValues.length - 1] = "*((array_int)+24300)@21";
|
||||
IExpressionDMContext[] arrayIntPartitions1 = getChildren(arrayIntPartitions[2], expectedValues);
|
||||
expectedValues = new String[21];
|
||||
for(int i = 0; i < expectedValues.length; ++i) {
|
||||
expectedValues[i] = String.format("array_int[%d]", 24300 + i);
|
||||
}
|
||||
getChildren(arrayIntPartitions1[arrayIntPartitions1.length - 1], expectedValues);
|
||||
|
||||
// foo array_foo[1200];
|
||||
IExpressionDMContext arrayFooExprDMC = SyncUtil.createExpression(frameDmc, "array_foo");
|
||||
getChildrenCount(arrayFooExprDMC, 12);
|
||||
expectedValues = new String[12];
|
||||
for (int i = 0; i < expectedValues.length; ++i) {
|
||||
expectedValues[i] = String.format("*((array_foo)+%d)@%d", i*100, 100);
|
||||
}
|
||||
IExpressionDMContext[] arrayFooPartitions = getChildren(arrayFooExprDMC, expectedValues);
|
||||
for (int i = 0; i < arrayFooPartitions.length; ++i) {
|
||||
IExpressionDMContext ctx = arrayFooPartitions[i];
|
||||
assertTrue(String.format("Invalid DM context type: expected '%s' got '%s'",
|
||||
IIndexedPartitionDMContext.class.getName(), ctx.getClass().getName()),
|
||||
ctx instanceof IIndexedPartitionDMContext);
|
||||
expectedValues = new String[100];
|
||||
for (int j = 0; j < expectedValues.length; ++j) {
|
||||
expectedValues[j] = String.format("array_foo[%d]", i*100 + j);
|
||||
}
|
||||
IExpressionDMContext[] arrayFooChildren = getChildren(ctx, expectedValues);
|
||||
// check the children of a couple of children
|
||||
getChildren(arrayFooChildren[0], new String[] {"bar", "bar2", "a", "b", "c"});
|
||||
getChildren(arrayFooChildren[80], new String[] {"bar", "bar2", "a", "b", "c"});
|
||||
|
||||
// get parts of the children array
|
||||
expectedValues = new String[] { String.format("array_foo[%d]", i*100 + 3), String.format("array_foo[%d]", i*100 + 4) };
|
||||
getChildren(ctx, 3, 2, expectedValues);
|
||||
getChildren(ctx, 99, 3, new String[] { String.format("array_foo[%d]", i*100 + 99) });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test verifies that large double arrays are properly partitioned
|
||||
*/
|
||||
@Test
|
||||
public void testLargeDoubleArray() throws Throwable {
|
||||
MIStoppedEvent stoppedEvent = SyncUtil.runToLocation("testArrays");
|
||||
|
||||
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
|
||||
|
||||
// char array_double_large[111][210]
|
||||
IExpressionDMContext arrayDoubleLargeExprDMC = SyncUtil.createExpression(frameDmc, "array_double_large");
|
||||
|
||||
getChildrenCount(arrayDoubleLargeExprDMC, 2);
|
||||
|
||||
// get top level partitions: [0-99], [100-110]
|
||||
IExpressionDMContext[] arrayTopPartitions =
|
||||
getChildren(arrayDoubleLargeExprDMC, new String[] {"*((array_double_large)+0)@100", "*((array_double_large)+100)@11"});
|
||||
assertTrue(String.format("Invalid number of partition: expected 2 got %d", arrayTopPartitions.length), arrayTopPartitions.length == 2);
|
||||
|
||||
// get children child array_double_large[100-110]
|
||||
IExpressionDMContext arrayDoubleLargeChildExprDMC = arrayTopPartitions[1];
|
||||
|
||||
getChildrenCount(arrayDoubleLargeChildExprDMC, 11);
|
||||
|
||||
String[] expectedValues = new String[11];
|
||||
for(int i = 0; i < expectedValues.length; ++i) {
|
||||
expectedValues[i] = String.format("array_double_large[%d]", 100 +i);
|
||||
}
|
||||
IExpressionDMContext[] arrayChild = getChildren(arrayDoubleLargeChildExprDMC, expectedValues);
|
||||
|
||||
// get second level partitions: array_double_large[101][0-99], [100-199], [200-209]
|
||||
IExpressionDMContext arrayDoubleLargeChildExprDMC2 = arrayChild[1];
|
||||
|
||||
getChildrenCount(arrayDoubleLargeChildExprDMC2, 3);
|
||||
|
||||
IExpressionDMContext[] arraySecondLevelPartitions =
|
||||
getChildren(arrayDoubleLargeChildExprDMC2, new String[] {"*((array_double_large[101])+0)@100",
|
||||
"*((array_double_large[101])+100)@100",
|
||||
"*((array_double_large[101])+200)@10"});
|
||||
assertTrue(String.format("Invalid number of partition: expected 3 got %d", arraySecondLevelPartitions.length), arraySecondLevelPartitions.length == 3);
|
||||
|
||||
// get children of array_double_large[101][0-99]
|
||||
IExpressionDMContext arrayDoubleLargeChildExprDMC3 = arraySecondLevelPartitions[0];
|
||||
|
||||
getChildrenCount(arrayDoubleLargeChildExprDMC3, 100);
|
||||
|
||||
expectedValues = new String[100];
|
||||
for(int i = 0; i < expectedValues.length; ++i) {
|
||||
expectedValues[i] = String.format("array_double_large[101][%d]", i);
|
||||
}
|
||||
IExpressionDMContext[] arrayChild2 = getChildren(arrayDoubleLargeChildExprDMC3, expectedValues);
|
||||
|
||||
// No more children for array_double_large[101][*]
|
||||
for (IExpressionDMContext ctx : arrayChild2)
|
||||
getChildren(ctx, new String[0]);
|
||||
|
||||
// get some parts of the children array
|
||||
getChildren(arrayDoubleLargeChildExprDMC3, 3, 2, new String[] { "array_double_large[101][3]", "array_double_large[101][4]" });
|
||||
getChildren(arrayDoubleLargeChildExprDMC3, 98, 3, new String[] { "array_double_large[101][98]","array_double_large[101][99]" });
|
||||
}
|
||||
|
||||
/**
|
||||
* This test verifies that "small" double arrays is not affected by partitions.
|
||||
*/
|
||||
@Test
|
||||
public void testSmallDoubleArray() throws Throwable {
|
||||
MIStoppedEvent stoppedEvent = SyncUtil.runToLocation("testArrays");
|
||||
|
||||
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
|
||||
|
||||
// int array_double_small[11][21];
|
||||
IExpressionDMContext arrayDoubleSmallExprDMC = SyncUtil.createExpression(frameDmc, "array_double_small");
|
||||
|
||||
getChildrenCount(arrayDoubleSmallExprDMC, 11);
|
||||
|
||||
// get all children of array_double_small
|
||||
String[] expectedValues = new String[11];
|
||||
for (int i = 0; i < expectedValues.length; ++i) {
|
||||
expectedValues[i] = String.format("array_double_small[%d]", i);
|
||||
}
|
||||
IExpressionDMContext[] arrayDoubleSmallChildren = getChildren(arrayDoubleSmallExprDMC, expectedValues);
|
||||
|
||||
// get all children of array_double_small[3]
|
||||
IExpressionDMContext arrayDoubleSmallChildExprDMC = arrayDoubleSmallChildren[3];
|
||||
|
||||
getChildrenCount(arrayDoubleSmallChildExprDMC, 21);
|
||||
|
||||
expectedValues = new String[21];
|
||||
for (int i = 0; i < expectedValues.length; ++i) {
|
||||
expectedValues[i] = arrayDoubleSmallChildExprDMC.getExpression() + "[" + i +"]";
|
||||
}
|
||||
IExpressionDMContext[] arrayDoubleSmallGrandChildren = getChildren(arrayDoubleSmallChildExprDMC, expectedValues);
|
||||
|
||||
// No more children for array_double_small[3][*]
|
||||
for (IExpressionDMContext ctx : arrayDoubleSmallGrandChildren)
|
||||
getChildren(ctx, new String[0]);
|
||||
|
||||
// get some parts of the children array
|
||||
getChildren(arrayDoubleSmallChildExprDMC, 3, 2, new String[] { "array_double_small[3][3]", "array_double_small[3][4]" });
|
||||
getChildren(arrayDoubleSmallChildExprDMC, 19, 3, new String[] { "array_double_small[3][19]","array_double_small[3][20]" });
|
||||
}
|
||||
|
||||
private int getChildrenCount(final IExpressionDMContext parentDmc, final int expectedCount) throws Throwable {
|
||||
|
||||
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
|
||||
|
||||
fExpService.getExecutor().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
fExpService.getSubExpressionCount(
|
||||
parentDmc,
|
||||
new DataRequestMonitor<Integer>(fExpService.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
wait.setReturnInfo(getData());
|
||||
if (getData() != expectedCount) {
|
||||
wait.waitFinished(
|
||||
new Status(
|
||||
IStatus.ERROR,
|
||||
TestsPlugin.PLUGIN_ID,
|
||||
String.format(
|
||||
"Failed getting count for children. Got %d instead of %d.",
|
||||
getData(),
|
||||
expectedCount)));
|
||||
}
|
||||
else {
|
||||
wait.waitFinished(getStatus());
|
||||
}
|
||||
}
|
||||
else {
|
||||
wait.waitFinished(getStatus());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertTrue(wait.getMessage(), wait.isOK());
|
||||
|
||||
int count = ((Integer)wait.getReturnInfo()).intValue();
|
||||
|
||||
assertTrue(String.format("Expected %d but got %d", expectedCount, count), count == expectedCount);
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
|||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMData;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IIndexedPartitionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions2;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions2.CastInfo;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions2.ICastedExpressionDMContext;
|
||||
|
@ -90,6 +91,9 @@ public class DsfCastToTypeSupport {
|
|||
}
|
||||
|
||||
private boolean isValid() {
|
||||
if (exprDMC instanceof IIndexedPartitionDMContext)
|
||||
return false;
|
||||
|
||||
TestExpressions2Query query = new TestExpressions2Query();
|
||||
dmvmProvider.getSession().getExecutor().execute(query);
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
|
|||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMData;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMLocation;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IIndexedPartitionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions2;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions3;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions3.IExpressionDMDataExtension;
|
||||
|
@ -135,6 +136,11 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
*/
|
||||
public static final String PROP_VARIABLE_ADDRESS_CHANGED = ICachingVMProvider.PROP_IS_CHANGED_PREFIX + PROP_VARIABLE_ADDRESS;
|
||||
|
||||
/**
|
||||
* 'PROP_VARIABLE_BASIC_TYPE' property value for indexed partitions
|
||||
*/
|
||||
private static final String INDEXED_PARTITION_TYPE = "indexed_partition_type"; //$NON-NLS-1$
|
||||
|
||||
private final SyncVariableDataAccess fSyncVariableDataAccess;
|
||||
|
||||
/**
|
||||
|
@ -330,6 +336,16 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
};
|
||||
};
|
||||
|
||||
public final static LabelImage PARTITION_LABEL_IMAGE = new LabelImage(CDebugImages.DESC_OBJS_ARRAY_PARTITION) {
|
||||
{ setPropertyNames(new String[] { PROP_VARIABLE_BASIC_TYPE }); }
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
|
||||
String type = (String)properties.get(PROP_VARIABLE_BASIC_TYPE);
|
||||
return INDEXED_PARTITION_TYPE.equals(type);
|
||||
};
|
||||
};
|
||||
|
||||
protected IElementLabelProvider createLabelProvider() {
|
||||
|
||||
//
|
||||
|
@ -407,6 +423,7 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
new String[] { PROP_NAME }),
|
||||
POINTER_LABEL_IMAGE,
|
||||
AGGREGATE_LABEL_IMAGE,
|
||||
PARTITION_LABEL_IMAGE,
|
||||
SIMPLE_LABEL_IMAGE,
|
||||
new StaleDataLabelForeground(),
|
||||
new VariableLabelFont(),
|
||||
|
@ -422,6 +439,7 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
new String[] { PROP_ELEMENT_EXPRESSION }),
|
||||
POINTER_LABEL_IMAGE,
|
||||
AGGREGATE_LABEL_IMAGE,
|
||||
PARTITION_LABEL_IMAGE,
|
||||
SIMPLE_LABEL_IMAGE,
|
||||
new StaleDataLabelForeground(),
|
||||
new VariableLabelFont(),
|
||||
|
@ -770,10 +788,13 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
// In case of an error fill in the expression text in the name column and expressions columns.
|
||||
IExpressionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExpressions.IExpressionDMContext.class);
|
||||
if (dmc != null && dmc.getExpression() != null) {
|
||||
update.setProperty(PROP_NAME, dmc.getExpression());
|
||||
String displayName = getExpressionDisplayName(dmc, dmc.getExpression());
|
||||
update.setProperty(PROP_NAME, displayName);
|
||||
if (expression == null) {
|
||||
update.setProperty(PROP_ELEMENT_EXPRESSION, dmc.getExpression());
|
||||
update.setProperty(PROP_ELEMENT_EXPRESSION, displayName);
|
||||
}
|
||||
if (dmc instanceof IIndexedPartitionDMContext)
|
||||
update.setProperty(PROP_VARIABLE_BASIC_TYPE, INDEXED_PARTITION_TYPE);
|
||||
}
|
||||
update.setStatus(getStatus());
|
||||
}
|
||||
|
@ -814,11 +835,23 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
@ConfinedToDsfExecutor("getSession().getExecutor()")
|
||||
protected void fillExpressionDataProperties(IPropertiesUpdate update, IExpressionDMData data)
|
||||
{
|
||||
update.setProperty(PROP_NAME, data.getName());
|
||||
IExpressionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExpressions.IExpressionDMContext.class);
|
||||
String displayName = data.getName();
|
||||
if (dmc != null) {
|
||||
displayName = getExpressionDisplayName(dmc, displayName);
|
||||
}
|
||||
update.setProperty(PROP_NAME, displayName);
|
||||
update.setProperty(PROP_VARIABLE_TYPE_NAME, data.getTypeName());
|
||||
IExpressionDMData.BasicType type = data.getBasicType();
|
||||
if (type != null) {
|
||||
update.setProperty(PROP_VARIABLE_BASIC_TYPE, type.name());
|
||||
String typeValue = null;
|
||||
if (dmc instanceof IIndexedPartitionDMContext)
|
||||
typeValue = INDEXED_PARTITION_TYPE;
|
||||
else {
|
||||
IExpressionDMData.BasicType type = data.getBasicType();
|
||||
if (type != null)
|
||||
typeValue = type.name();
|
||||
}
|
||||
if (typeValue != null) {
|
||||
update.setProperty(PROP_VARIABLE_BASIC_TYPE, typeValue);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -828,7 +861,7 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
//
|
||||
IExpression expression = (IExpression)DebugPlugin.getAdapter(update.getElement(), IExpression.class);
|
||||
if (expression == null) {
|
||||
update.setProperty(AbstractExpressionVMNode.PROP_ELEMENT_EXPRESSION, data.getName());
|
||||
update.setProperty(AbstractExpressionVMNode.PROP_ELEMENT_EXPRESSION, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1344,4 +1377,18 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
request.done();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the label for the element with the given context.
|
||||
*/
|
||||
protected String getExpressionDisplayName(IExpressionDMContext dmc, String name) {
|
||||
if (dmc instanceof IIndexedPartitionDMContext) {
|
||||
IIndexedPartitionDMContext ipDmc = (IIndexedPartitionDMContext)dmc;
|
||||
name = String.format(
|
||||
"[%d...%d]", //$NON-NLS-1$
|
||||
ipDmc.getIndex(),
|
||||
ipDmc.getIndex() + ipDmc.getLength() - 1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,30 @@ public interface IExpressions extends IFormattedValues {
|
|||
String getExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
* To avoid SWT performance issues large arrays are divided into partitions.
|
||||
* This interface represents the context of such a partition.
|
||||
*
|
||||
* @since 2.3
|
||||
*/
|
||||
public interface IIndexedPartitionDMContext extends IExpressionDMContext {
|
||||
|
||||
/**
|
||||
* Returns the expression string of the parent array.
|
||||
*/
|
||||
public String getParentExpression();
|
||||
|
||||
/**
|
||||
* Returns the index of the partition's first element in the parent array.
|
||||
*/
|
||||
public int getIndex();
|
||||
|
||||
/**
|
||||
* Returns the number of array's elements in the partition.
|
||||
*/
|
||||
public int getLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* The address and size of an expression.
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue