/** * Performs a search for a member with the given name using the given id as the parent variable. * * <p>If a match is found then, we return the parent variable of the member that matched. The * proto chain is optionally traversed. * * <p>No exceptions are thrown */ Value locateParentForNamed(long id, String name, boolean traverseProto) throws PlayerDebugException { StringBuilder sb = new StringBuilder(); Variable var = null; Value val = null; try { var = memberNamed(id, name); // see if we need to traverse the proto chain while (var == null && traverseProto) { // first attempt to get __proto__, then resolve name Variable proto = memberNamed(id, "__proto__"); // $NON-NLS-1$ sb.append("__proto__"); // $NON-NLS-1$ if (proto == null) traverseProto = false; else { id = proto.getValue().getId(); var = memberNamed(id, name); if (var == null) sb.append('.'); } } } catch (NoSuchVariableException nsv) { // don't worry about this one, it means variable with id couldn't be found } catch (NullPointerException npe) { // probably no session } // what we really want is the parent not the child variable if (var != null) { pushName(sb.toString()); val = getSession().getWorkerSession(m_isolateId).getValue(id); } return val; }
// assign the object o, the value v public void assign(Object o, Value v) throws NoSuchVariableException, PlayerFaultException { try { // first see if it is an internal property (avoids player calls) InternalProperty prop = resolveToInternalProperty(o); // we expect that o is a variable that can be resolved or is a specially marked internal // variable if (prop != null) { assignInternal(prop, v); } else { boolean wasCreateIfMissing = m_createIfMissing; createPseudoVariables(true); Variable var = null; try { var = resolveToVariable(o); } finally { createPseudoVariables(wasCreateIfMissing); } if (var == null) throw new NoSuchVariableException(m_current); // set the value, for the case of a variable that does not exist it will not have a type // so we try to glean one from v. FaultEvent faultEvent = var.setValue(getSession(), v.getType(), v.getValueAsString()); if (faultEvent != null) throw new PlayerFaultException(faultEvent); } } catch (PlayerDebugException pde) { throw new ExpressionEvaluatorException(pde); } }
/* returns a string consisting of formatted member names and values */ public Object lookupMembers(Object o) throws NoSuchVariableException { Variable var = null; Value val = null; Variable[] mems = null; try { var = resolveToVariable(o); if (var != null) val = var.getValue(); else val = resolveToValue(o); mems = val.getMembers(getSession()); } catch (NullPointerException npe) { throw new NoSuchVariableException(o); } catch (PlayerDebugException pde) { throw new NoSuchVariableException(o); // not quite right... } StringBuilder sb = new StringBuilder(); if (var != null) m_cache.appendVariable(sb, var, m_isolateId); else m_cache.appendVariableValue(sb, val, m_isolateId); boolean attrs = m_cache.propertyEnabled(DebugCLI.DISPLAY_ATTRIBUTES); if (attrs && var != null) ExpressionCache.appendVariableAttributes(sb, var); // [mmorearty] experimenting with hierarchical display of members String[] classHierarchy = val.getClassHierarchy(false); if (classHierarchy != null && getSession().getPreference(SessionManager.PREF_HIERARCHICAL_VARIABLES) != 0) { for (int c = 0; c < classHierarchy.length; ++c) { String classname = classHierarchy[c]; sb.append(m_newline + "(Members of " + classname + ")"); // $NON-NLS-1$ //$NON-NLS-2$ for (int i = 0; i < mems.length; ++i) { if (classname.equals(mems[i].getDefiningClass())) { sb.append(m_newline + " "); // $NON-NLS-1$ m_cache.appendVariable(sb, mems[i], m_isolateId); if (attrs) ExpressionCache.appendVariableAttributes(sb, mems[i]); } } } } else { for (int i = 0; i < mems.length; i++) { sb.append(m_newline + " "); // $NON-NLS-1$ m_cache.appendVariable(sb, mems[i], m_isolateId); if (attrs) ExpressionCache.appendVariableAttributes(sb, mems[i]); } } return sb.toString(); }
/** * All the really good stuff about finding where name exists goes here! * * <p>If name is not null, then it implies that we use the existing m_current to find a member of * m_current. If m_current is null Then we need to probe variable context points attempting to * locate name. When we find a match we set the m_current to this context * * <p>If name is null then we simply return the current context. */ long determineContext(String name) throws PlayerDebugException { long id = Value.UNKNOWN_ID; // have we already resolved our context... if (m_current != null) { id = toValue().getId(); } // nothing to go on, so we're done else if (name == null) ; // use the name and try and resolve where we are... else { // Each stack frame has a root variable under (BASE_ID-depth) // where depth is the depth of the stack. // So we query for our current stack depth and use that // as the context for our base computation long baseId = Value.BASE_ID; int depth = ((Integer) m_cache.get(DebugCLI.DISPLAY_FRAME_NUMBER)).intValue(); baseId -= depth; // obtain data about our current state Variable contextVar = null; Value contextVal = null; Value val = null; // look for 'name' starting from local scope if ((val = locateParentForNamed(baseId, name, false)) != null) ; // get the this pointer, then look for 'name' starting from that point else if (((contextVar = locateForNamed(baseId, "this", false)) != null) && //$NON-NLS-1$ (setName("this") && (val = locateParentForNamed(contextVar.getValue().getId(), name, true)) != null)) //$NON-NLS-1$ ; // now try to see if 'name' exists off of _root else if (setName("_root") && (val = locateParentForNamed(Value.ROOT_ID, name, true)) != null) // $NON-NLS-1$ ; // now try to see if 'name' exists off of _global else if (setName("_global") && (val = locateParentForNamed(Value.GLOBAL_ID, name, true)) != null) // $NON-NLS-1$ ; // now try off of class level, if such a thing can be found else if (((contextVal = locate(Value.GLOBAL_ID, getCurrentPackageName(), false)) != null) && (setName("_global." + getCurrentPackageName()) && (val = locateParentForNamed(contextVal.getId(), name, true)) != null)) //$NON-NLS-1$ ; // if we found it then stake this as our context! if (val != null) { id = val.getId(); pushName(name); lockName(); } } return id; }