/******************************************************************************* * Copyright (c) 2010 Nokia 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: * Nokia - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.dsf.debug.service; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; /** * This interface extends the expressions service with support for casting to type or * array. * @since 2.1 */ public interface IExpressions2 extends IExpressions { /** * This class specifies how an expression should be * typecast to another type and/or displayed as an array. */ public static class CastInfo { private final String typeString; private final int arrayCount; private final int arrayStart; /** * Create an instance of casting information * @param typeString if not <code>null</code>, the C/C++ type to which to cast the expression (e.g. "char**") * @param arrayStart if arrayCount > 0, the start index for viewing contents of the expression as an array * @param arrayCount if > 0, indicates to show [arrayStart ... arrayStart+arrayCount) as child expressions */ public CastInfo(String typeString, int arrayStart, int arrayCount) { this.typeString = typeString; this.arrayStart = arrayStart; this.arrayCount = arrayCount; } /** * Create an instance of casting information for casting to type (only) * @param typeString must be non-<code>null</code>; the C/C++ type to which to cast the expression (e.g. "char**") */ public CastInfo(String typeString) { if (typeString == null) throw new IllegalArgumentException(); this.typeString = typeString; this.arrayStart = this.arrayCount = 0; } /** * Create an instance of casting information for showing as an array (only) * @param arrayStart the start index for viewing contents of the expression as an array * @param arrayCount must be > 0; indicates to show [arrayStart ... arrayStart+arrayCount) as child expressions */ public CastInfo(int arrayStart, int arrayCount) { if (arrayCount <= 0) throw new IllegalArgumentException(); this.typeString = null; this.arrayStart = arrayStart; this.arrayCount = arrayCount; } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + arrayCount; result = prime * result + arrayStart; result = prime * result + ((typeString == null) ? 0 : typeString.hashCode()); return result; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; CastInfo other = (CastInfo) obj; if (arrayCount != other.arrayCount) return false; if (arrayStart != other.arrayStart) return false; if (typeString == null) { if (other.typeString != null) return false; } else if (!typeString.equals(other.typeString)) return false; return true; } /** * Get the user-friendly type name. This may be a post-processed string * but should be semantically equivalent to the type used to create the context. * @return type string, or <code>null</code> if no type casting performed */ public String getTypeString() { return typeString; } /** * Get the start index for viewing children as an array. (Only effective if #getCount() > 0) * @return the index of the first element of the array. 0 means that * the original element is the first member of the array. This may be negative, too. */ public int getArrayStartIndex(){ return arrayStart; } /** * Get the number of elements to show when viewing children as an array. * @return the array size, or <= 0 if not viewing as an array */ public int getArrayCount(){ return arrayCount; } } /** * This context identifies a casted expression. Its parent is the original * {@link IExpressionDMContext}. */ public interface ICastedExpressionDMContext extends IExpressionDMContext { CastInfo getCastInfo(); } /** * Create a variant of the expression which is casted with the given casting info. * <p> * If {@link ICastInfo#getTypeString()} is not <code>null</code>, such an expression should * report the casted type via {@link IExpressionDMData} and generate subexpressions accordingly. * <p> * Note that typically, a cast of a primitive type (int, double, etc.) to another * primitive type is interpreted as "*(other_type*)&(expression)", not merely * as casting the rvalue of "expression" to another type (which usually only * truncates or extends the value without much benefit). * <p> * If {@link ICastInfo#getArrayCount()} is greater than <code>0</code>, the expression should * yield that number of elements as subexpressions, as array elements, starting with index * {@link ICastInfo#getArrayStartIndex()}. (This does not affect the address of the * expression itself, only which children are returned.) * <p> * The expected semantics of an array cast ranging from J to K are to take a * pointer-valued expression whose base type is size N, evaluate its value * to A, and yield array elements of the pointer base type at locations * <code>A + N*J</code>, <code>A + N*(J+1)</code>, ..., * <code>A + N*(J+K-1)</code>. But the address of the expression is <b>not</b> modified * when an array cast is applied. * <p>An implementation may provide its own semantics for viewing other data as arrays, if so desired. * @param context an existing expression * @param castInfo the casting information * @return a casted expression data model context object that must be passed to the appropriate * data retrieval routine to obtain the value of the expression. The object must * report the casted type (if any) via {@link #getExpressionData(IExpressionDMContext, DataRequestMonitor)} * and report alternate children according to the array casting context via * {@link #getSubExpressionCount(IExpressionDMContext, DataRequestMonitor)} * and {@link #getSubExpressions}. */ ICastedExpressionDMContext createCastedExpression(IExpressionDMContext context, CastInfo castInfo); }