diff --git a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetObject.java b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetObject.java index 7a47452a9d..d5d7593965 100644 --- a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetObject.java +++ b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetObject.java @@ -47,22 +47,22 @@ import ghidra.lifecycle.Internal; * root object, may implement any number of interfaces extending {@link TargetObject}. These * interfaces comprise the type and behavior of the object. An object's children comprise its * elements (for collection-like objects) and attributes. Every object in the directory has a path. - * Each element in the path identifies an index (if the child is an element) or a name (if the child - * is an attribute). It is the implementation's responsibility to ensure each object's path - * correctly identifies that same object in the model directory. The root has the empty path. Every - * object must have a unique path; thus, every object must have a unique name among its sibling. + * Each element ("key") in the path identifies an index (if the child is an element) or a name (if + * the child is an attribute). It is the implementation's responsibility to ensure each object's + * path correctly identifies that same object in the model directory. The root has the empty path. + * Every object must have a unique path; thus, every object must have a unique key among its + * sibling. * *
* The objects are arranged in a directory with links permitted. Links come in the form of - * object-valued attributes where the attribute path is not its value's path. Thus, the overall - * structure remains a tree, but by resolving links, the model may be treated as a directed graph, - * likely containing cycles. See {@link PathUtils#isLink(List, String, List)}. + * object-valued attributes or elements where the path does not match the object value's path. Thus, + * the overall structure remains a tree, but by resolving links, the model may be treated as a + * directed graph, likely containing cycles. See {@link PathUtils#isLink(List, String, List)}. * *
* The implementation must guarantee that distinct {@link TargetObject}s from the same model do not - * refer to the same path. That is, checking for object identity is sufficient to check that two - * variables refer to the same object. It is recommended that client-side implementations use a - * weak-valued map of paths to cached target objects. + * share the same path. That is, checking for object identity is sufficient to check that two + * variables refer to the same object. * *
* Various conventions govern where the client/user should search to obtain a given interface in the @@ -78,7 +78,7 @@ import ghidra.lifecycle.Internal; * If it does, take it. *
* This relatively free structure and corresponding conventions allow for debuggers to present a
@@ -307,9 +307,13 @@ public interface TargetObject extends Comparable
* Because interfaces cannot provide default implementations of {@link #equals(Object)}, this
- * methods provides a means of quickly implementing it within a class. Because everything that
- * constitutes target object equality is contained in the reference (model, path), there should
- * never be a need to perform more comparison than is provided here.
+ * methods provides a means of quickly implementing it within a class. Because (model, path)
+ * uniquely identifies an object, there should never be a need to perform more comparison than
+ * is provided here.
+ *
+ *
+ * TODO: Since refs are no longer a thing, is custom equality needed at all? Seems object
+ * identity would be sufficient.
*
* @param obj the other object
* @return true if they are equal
@@ -331,10 +335,14 @@ public interface TargetObject extends Comparable
* Because interfaces cannot provide default implementations of {@link #hashCode()}, this method
- * provides a means of quickly implementing it within a class. Because everything that
- * constitutes target object equality is immutable and contained in the reference
- * (model, path), this hash should be pre-computed a construction. There should never be a need
- * to incorporate more fields into the hash than is incorporated here.
+ * provides a means of quickly implementing it within a class. Because (model, path) is
+ * immutable and uniquely identifes an object, this hash should be pre-computed a construction.
+ * There should never be a need to incorporate more fields into the hash than is incorporated
+ * here.
+ *
+ *
+ * TODO: Since refs are no longer a thing, is custom equality needed at all? Seems object
+ * identity would be sufficient.
*
* @return the hash
*/
@@ -409,8 +417,8 @@ public interface TargetObject extends Comparable
- * Every object must have a unique path. Parts of the path which are indices, i.e., which
- * navigate the elements, are enclosed in brackets @{code []}. Parts which navigate attributes
+ * Every object must have a unique path. Keys in the path which are indices, i.e., which
+ * navigate the elements, are enclosed in brackets @{code []}. Keys which navigate attributes
* are simply the attribute name.
*
*
@@ -418,9 +426,6 @@ public interface TargetObject extends Comparable
* Note that no check is applied to guarantee the path separator does not appear in an element
- * name.
+ * name. Conventionally, `.` should be the separator. The separator is omitted before indices.
*
* @see #getPath()
* @param sep the path separator
@@ -455,10 +460,10 @@ public interface TargetObject extends Comparable
* This is an informal notion of type and may only be used for visual styling, logging, or other
* informational purposes. Scripts should not rely on this to predict behavior, but instead on
- * {@link #getAs(Class)} or {@link #getInterfaces()};
+ * {@link #getAs(Class)}, {@link #getInterfaces()}, or {@link #getSchema()}.
*
* @return an informal name of this object's type
*/
public String getTypeHint();
/**
- * Get this object's schema.
+ * Get this object's schema
*
* @return the schema
*/
@@ -502,7 +507,7 @@ public interface TargetObject extends Comparable
* When this object is a proxy, this set must include the names of all interfaces reported by
@@ -530,10 +535,10 @@ public interface TargetObject extends Comparable
* In general, an invalid object should be disposed by the user immediately on discovering it is
- * invalid. See {@link TargetObjectListener#invalidated(TargetObject)} for a means of reacting
+ * invalid. See {@link DebuggerModelListener#invalidated(TargetObject)} for a means of reacting
* to object invalidation. Nevertheless, it is acceptable to access stale attributes and element
* keys, for informational purposes only. Implementors must reject all commands, including
- * non-cached gets, on an invalid object by throwing an {@link IllegalStateException}.
+ * fetches, on an invalid object by throwing an {@link IllegalStateException}.
*
* @return true if valid, false if invalid
*/
@@ -546,12 +551,6 @@ public interface TargetObject extends Comparable
- * Note, for objects, {@link TargetObject#getCachedAttributes()} should be sufficient to get an
- * up-to-date view of the attributes, since the model should be pushing attribute updates to the
- * object automatically. {@code fetchAttributes} should only be invoked on references, or in the
- * rare case the client needs to ensure the attributes are fresh.
- *
* @param refresh true to invalidate all caches involved in handling this request
* @return a future which completes with a name-value map of attributes
*/
@@ -604,18 +603,6 @@ public interface TargetObject extends Comparable
- * Note these are cached elements, and there's no requirement on the model's part to keep this
- * cache up to date (unlike attributes). Thus, the indices (keys) in the returned map may be
- * out-of-date.
- *
- *
- * Note that this method is not required to provide objects, but only object references. Local
- * implementations, and clients having the appropriate proxies cached may present some, all, or
- * none of the entries with actual objects. Users should NEVER depend on this being the case,
- * however. Always call {@link TargetObjectRef#fetch()}, or use {@link #fetchElements} instead,
- * to guarantee the actual objects are presented.
- *
* @return the map of indices to element references
*/
public Map
- * Elements are usually keyed numerically, but allows strings for flexibility. They values are
- * target objects, uniform in type, and should generally share the same attributes. The keys
- * must not contain the brackets {@code []}. Implementations should ensure that the elements are
+ * Elements are usually keyed numerically, but allows strings for flexibility. The values are
+ * target objects, typically uniform in type, and so generally share the same attributes. The
+ * keys must omit the brackets {@code []}. Implementations should ensure that the elements are
* presented in order by key -- not necessarily lexicographically. To ensure clients can easily
* maintain correct sorting, the recommendation is to present the keys as follows: Keys should
* be the numeric value encoded as strings in base 10 or base 16 as appropriate, using the least
@@ -654,7 +641,7 @@ public interface TargetObject extends Comparable
* Indices are distinguished from names by the presence or absence of brackets {@code []}. If
- * the key is a bracket-enclosed index, this will retrieve a child, otherwise, it will retrieve
- * an attribute.
+ * the key is a bracket-enclosed index, this will retrieve an element, otherwise, it will
+ * retrieve an attribute.
*
* @see #fetchAttribute(String)
* @see #fetchElement(String)
@@ -763,7 +750,8 @@ public interface TargetObject extends Comparable
* Extend this reference's path with the given sub-path and request that object from the same
- * model.
+ * model. Note unlike {@link #fetchValue(List)}, this can return objects which have been
+ * created, but not yet added to the model.
*
* @param sub the sub-path to the successor
* @return a future which completes with the object or with {@code null} if it does not exist
@@ -780,14 +768,13 @@ public interface TargetObject extends Comparable
- * Extend this reference's path with the given sub-path, creating a new reference in the same
- * model. This is mere path manipulation. The referenced object may not exist.
+ * Extend this object's path with the given sub-path, and search the model's cache for it.
*
* @param sub the sub-path to the successor
- * @return a reference to the successor
+ * @return the successor or {@code null} if it doesn't exist in the cache
*/
public default TargetObject getSuccessor(List
* This is useful when the native debugger presents a comparable tree-like model. If this object
@@ -942,7 +929,7 @@ public interface TargetObject extends Comparable
- * TODO: This should probably be moved to a new {@code TargetType} interface.
+ * TODO: This should probably be moved to a new {@code TargetObject} interface.
*
*
* "Recently" generally means since (or as a result of ) the last event affecting a target in
@@ -960,7 +947,7 @@ public interface TargetObject extends Comparable
- * TODO: This should probably be moved to a new {@code TargetType} interface. How does this
+ * TODO: This should probably be moved to a new {@code TargetObject} interface. How does this
* differ from "kind" when both are present? Can this be a {@link TargetNamedDataType} instead?
* Though, I suppose that would imply the object is a value in the target execution state, e.g.,
* a register, variable, field, etc.
@@ -976,7 +963,7 @@ public interface TargetObject extends Comparable
- * TODO: This should probably be moved to a new {@code TargetType} interface.
+ * TODO: This should probably be moved to a new {@code TargetObject} interface.
*
* @return the value
*/
@@ -1014,7 +1001,7 @@ public interface TargetObject extends Comparable
* The opaque identifier should implement proper {@link Object#hashCode()} and
- * {@link Object#equals(Object)}, so that paired with the client, it forms a unique key for this
+ * {@link Object#equals(Object)}, so that paired with the model, it forms a unique key for this
* target object. It should also implement {@link Object#toString()}; however, it is for
* debugging or informational purposes only. It is common for this identifier to be the object's
* path.
@@ -1024,7 +1011,14 @@ public interface TargetObject extends Comparable
+ * This differs from Java-style casting in two ways: 1) The receiver cannot be {@code null}, and
+ * 2) It throws a different exception. Server-side proxy implementations must marshall the
+ * {@link DebuggerModelTypeException} to the client; whereas, for {@link ClassCastException}, it
+ * may simply report "Server-side Error," because that exception may have been thrown by an
+ * unrelated cast.
*
* @param
- * While this technically only returns "cached" attributes, the model should be pushing
- * attribute updates to the object automatically. Thus, the names (keys) and values in the
- * returned map should be up-to-date.
- *
- *
- * Note that object-valued attributes are only guaranteed to be a {@link TargetObjectRef}. Local
- * implementations, and clients having the appropriate proxies cached may present some, all, or
- * none of the object-valued attributes with the actual object. Users should NEVER depend on
- * this being the case, however. Always call {@link TargetObjectRef#fetch()}, or use
- * {@link #fetchAttributes()} instead, to guarantee the actual objects are presented.
- *
* @return the cached name-value map of attributes
*/
public Map
* Some objects, e.g., memories and register banks, may have caches to reduce requests and
- * callbacks. This method should clear such caches, if applicable, but should not clear
+ * callbacks. This method should clear such caches, if applicable, but must not clear
* caches of elements or attributes.
*
*
@@ -1107,14 +1089,21 @@ public interface TargetObject extends Comparable
- * The caller must maintain a strong reference to the listener. To allow stale listeners to be
+ * The client must maintain a strong reference to the listener. To allow stale listeners to be
* garbage collected, the implementation should use weak or soft references. That said, the
- * client user must not rely on the implementation to garbage collect its listeners. All
- * unneeded listeners should be removed using {@link #removeListener(TargetObjectListener)}. The
- * exception is when an object is destroyed. The user may safely neglect removing any listeners
- * it registered with that object. If the object does not keep listeners, i.e., it produces no
- * events, this method may do nothing.
+ * client should not rely on the implementation to garbage collect its listeners. All unneeded
+ * listeners should be removed using {@link #removeListener(TargetObjectListener)}. The
+ * exception is when an object is invalidated. The client may safely neglect removing any
+ * listeners it registered with that object. If the object does not keep listeners, i.e., it
+ * produces no events, this method may do nothing.
*
+ *
+ * Clients ought to listen on the model instead of specific objects, especially since an object
+ * may emit events immediately after its creation, but before the client has a chance to add a
+ * listener. Worse yet, the object could be invalidated before the client can retrieve its
+ * children. Listening on the model ensures the reception of a complete log of events.
+ *
+ * @see DebuggerObjectModel#addModelListener(DebuggerModelListener)
* @param l the listener
*/
public default void addListener(TargetObjectListener l) {
@@ -1125,7 +1114,7 @@ public interface TargetObject extends Comparable
- * If the given listener is not registered with this object, this method should do nothing.
+ * If the given listener is not registered with this object, this method does nothing.
*
* @param l the listener
*/