} // triggers a reload of variables. /// <summary> Removes the specified variable from the list of locals, and /// remembers that the specified variable is the "activation object" /// for this frame. See bug 155031. /// </summary> internal virtual void convertLocalToActivationObject(DVariable v) { m_activationObject = v; m_locals.Remove(v.getName()); }
/* setters */ internal virtual void addArgument(DVariable v) { m_args[v.getName()] = v; }
internal virtual void addLocal(DVariable v) { m_locals[v.getName()] = v; }
internal virtual void addVariableMember(DValue parent, DVariable child) { if (m_attachChildren) { // There are certain situations when the Flash player will send us more // than one variable or getter with the same name. Basically, when a // subclass implements (or overrides) something that was also declared in a // superclass, then we'll see that variable or getter in both the // superclass and the subclass. // // Here are a few situations where that affects the debugger in different // ways: // // 1. When a class implements an interface, the class instance actually has // *two* members for each implemented function: One which is public and // represents the implementation function, and another which is internal // to the interface, and represents the declaration of the function. // Both of these come in to us. In the UI, the one we want to show is // the public one. They come in in random order (they are stored in a // hash table in the VM), so we don't know which one will come first. // // 2. When a superclass has a private member "m", and a subclass has its own // private member with the same name "m", we will receive both of them. // (They are scoped by different packages.) In this case, the first one // the player sent us is the one from the subclass, and that is the one // we want to display in the debugger. // // The following logic correctly deals with all variations of those cases. DVariable existingChildWithSameName = parent.findMember(child.getName()); if (existingChildWithSameName != null) { int existingScope = existingChildWithSameName.Scope; int newScope = child.Scope; if (existingScope == VariableAttribute.NAMESPACE_SCOPE && newScope == VariableAttribute.PUBLIC_SCOPE) { // This is the case described above where a class implements an interface, // so that class's definition includes both a namespace-scoped declaration // and a public declaration, in random order; in this case, the // namespace-scoped declaration came first. We want to use the public // declaration. parent.addMember(child); } else if (existingScope == VariableAttribute.PUBLIC_SCOPE && newScope == VariableAttribute.NAMESPACE_SCOPE) { // One of two things happened here: // // 1. This is the case described above where a class implements an interface, // so that class's definition includes both a namespace-scoped declaration // and a public declaration, in random order; in this case, the // public declaration came first. It is tempting to use the public // member in this case, but there is a catch... // 2. It might be more complicated than that: Perhaps there is interface I, // and class C1 implements I, but class C2 extends C1, and overrides // one of the members of I that was already implemented by C1. In this // case, the public declaration from C2 came first, but now we are seeing // a namespace-scoped declaration in C1. We need to record that the // member is public, but we also need to record that it is a member // of the base class, not just a member of the superclass. // // The easiest way to deal with both cases is to use the child that came from // the superclass, but to change its scope to public. child.makePublic(); parent.addMember(child); } else if (existingScope != VariableAttribute.PRIVATE_SCOPE && existingScope == newScope) { // This is a public, protected, internal, or namespace-scoped member which // was defined in a base class and overridden in a subclass. We want to // use the member from the base class, to that the debugger knows where the // variable was actually defined. parent.addMember(child); } } else { parent.addMember(child); } // put child in the registry if it has an id and not already there DValue childValue = (DValue) child.getValue(); int childId = childValue.Id; if (childId != Value.UNKNOWN_ID) { DValue existingValue = getValue(childId); if (existingValue != null) { Debug.Assert(existingValue == childValue); // TODO is this right? what about getters? } else { putValue(childId, childValue); } } } }
public virtual void addMember(DVariable v) { if (m_members == null) { m_members = new System.Collections.Hashtable(); } // if we are a proto member house away our original parent id String name = v.getName(); DValue val = (DValue) v.getValue(); val.m_nonProtoId = (name != null && name.Equals("__proto__"))?m_nonProtoId:val.Id; //$NON-NLS-1$ // TODO is this right? v.m_nonProtoParentId = m_nonProtoId; m_members[name] = v; }