Java Code Examples for com.google.javascript.rhino.TokenStream#isJSIdentifier()

The following examples show how to use com.google.javascript.rhino.TokenStream#isJSIdentifier() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Cardumen_00200_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name is a valid variable name.
 */
static boolean isValidSimpleName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, Unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 2
Source File: 1_NodeUtil.java    From SimFix with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Determines whether the given name can appear on the right side of
 * the dot operator. Many properties (like reserved words) cannot.
 */
static boolean isValidPropertyName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 3
Source File: Closure_75_NodeUtil_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name can appear on the right side of
 * the dot operator. Many properties (like reserved words) cannot.
 */
static boolean isValidPropertyName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 4
Source File: Cardumen_00149_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name is a valid variable name.
 */
static boolean isValidSimpleName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, Unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 5
Source File: Closure_94_NodeUtil_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name can appear on the right side of
 * the dot operator. Many properties (like reserved words) cannot.
 */
static boolean isValidPropertyName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 6
Source File: Closure_86_NodeUtil_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name can appear on the right side of
 * the dot operator. Many properties (like reserved words) cannot.
 */
static boolean isValidPropertyName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 7
Source File: Closure_10_NodeUtil_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name is a valid variable name.
 */
static boolean isValidSimpleName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, Unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 8
Source File: Closure_80_NodeUtil_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name can appear on the right side of
 * the dot operator. Many properties (like reserved words) cannot.
 */
static boolean isValidPropertyName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 9
Source File: RenamePrototypes.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.GETPROP:
    case Token.GETELEM:
      Node dest = n.getFirstChild().getNext();
      if (dest.isString()) {
        String s = dest.getString();
        if (s.equals("prototype")) {
          processPrototypeParent(parent, t.getInput());
        } else {
          markPropertyAccessCandidate(dest, t.getInput());
        }
      }
      break;
    case Token.OBJECTLIT:
      if (!prototypeObjLits.contains(n)) {
        // Object literals have their property name/value pairs as a flat
        // list as their children. We want every other node in order to get
        // only the property names.
        for (Node child = n.getFirstChild();
             child != null;
             child = child.getNext()) {

          if (TokenStream.isJSIdentifier(child.getString())) {
            markObjLitPropertyCandidate(child, t.getInput());
          }
        }
      }
      break;
  }
}
 
Example 10
Source File: Closure_49_MakeDeclaredNamesUnique_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * @return Whether the name is valid to use in the local scope.
 */
private boolean isValidName(String name) {
  if (TokenStream.isJSIdentifier(name) &&
      !referencedNames.contains(name) &&
      !name.equals(ARGUMENTS)) {
    return true;
  }
  return false;
}
 
Example 11
Source File: MakeDeclaredNamesUnique.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * @return Whether the name is valid to use in the local scope.
 */
private boolean isValidName(String name) {
  if (TokenStream.isJSIdentifier(name) &&
      !referencedNames.contains(name) &&
      !name.equals(ARGUMENTS)) {
    return true;
  }
  return false;
}
 
Example 12
Source File: Closure_10_NodeUtil_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name is a valid variable name.
 */
static boolean isValidSimpleName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, Unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 13
Source File: jMutRepair_003_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name is a valid variable name.
 */
static boolean isValidSimpleName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, Unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 14
Source File: Closure_61_NodeUtil_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether the given name can appear on the right side of
 * the dot operator. Many properties (like reserved words) cannot.
 */
static boolean isValidPropertyName(String name) {
  return TokenStream.isJSIdentifier(name) &&
      !TokenStream.isKeyword(name) &&
      // no Unicode escaped characters - some browsers are less tolerant
      // of Unicode characters that might be valid according to the
      // language spec.
      // Note that by this point, unicode escapes have been converted
      // to UTF-16 characters, so we're only searching for character
      // values, not escapes.
      isLatin(name);
}
 
Example 15
Source File: Closure_89_GlobalNamespace_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the fully qualified name corresponding to an object literal key,
 * as long as it and its prefix property names are valid JavaScript
 * identifiers. The object literal may be nested inside of other object
 * literals.
 *
 * For example, if called with node {@code n} representing "z" in any of
 * the following expressions, the result would be "w.x.y.z":
 * <code> var w = {x: {y: {z: 0}}}; </code>
 * <code> w.x = {y: {z: 0}}; </code>
 * <code> w.x.y = {'a': 0, 'z': 0}; </code>
 *
 * @param n A child of an OBJLIT node
 * @return The global name, or null if {@code n} doesn't correspond to the
 *   key of an object literal that can be named
 */
String getNameForObjLitKey(Node n) {
  Node parent = n.getParent();
  Preconditions.checkState(parent.getType() == Token.OBJECTLIT);

  Node gramps = parent.getParent();
  if (gramps == null) {
    return null;
  }

  Node greatGramps = gramps.getParent();
  String name;
  switch (gramps.getType()) {
    case Token.NAME:
      // VAR
      //   NAME (gramps)
      //     OBJLIT (parent)
      //       STRING (n)
      if (greatGramps == null ||
          greatGramps.getType() != Token.VAR) {
        return null;
      }
      name = gramps.getString();
      break;
    case Token.ASSIGN:
      // ASSIGN (gramps)
      //   NAME|GETPROP
      //   OBJLIT (parent)
      //     STRING (n)
      Node lvalue = gramps.getFirstChild();
      name = lvalue.getQualifiedName();
      break;
    case Token.STRING:
      // OBJLIT
      //   STRING (gramps)
      //     OBJLIT (parent)
      //       STRING (n)
      if (greatGramps != null &&
          greatGramps.getType() == Token.OBJECTLIT) {
        name = getNameForObjLitKey(gramps);
      } else {
        return null;
      }
      break;
    default:
      return null;
  }
  if (name != null) {
    String key = n.getString();
    if (TokenStream.isJSIdentifier(key)) {
      return name + '.' + key;
    }
  }
  return null;
}
 
Example 16
Source File: Nopol2017_0014_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the fully qualified name corresponding to an object literal key,
 * as long as it and its prefix property names are valid JavaScript
 * identifiers. The object literal may be nested inside of other object
 * literals.
 *
 * For example, if called with node {@code n} representing "z" in any of
 * the following expressions, the result would be "w.x.y.z":
 * <code> var w = {x: {y: {z: 0}}}; </code>
 * <code> w.x = {y: {z: 0}}; </code>
 * <code> w.x.y = {'a': 0, 'z': 0}; </code>
 *
 * @param n A child of an OBJLIT node
 * @return The global name, or null if {@code n} doesn't correspond to the
 *   key of an object literal that can be named
 */
String getNameForObjLitKey(Node n) {
  Node parent = n.getParent();
  Preconditions.checkState(parent.isObjectLit());

  Node gramps = parent.getParent();
  if (gramps == null) {
    return null;
  }

  Node greatGramps = gramps.getParent();
  String name;
  switch (gramps.getType()) {
    case Token.NAME:
      // VAR
      //   NAME (gramps)
      //     OBJLIT (parent)
      //       STRING (n)
      if (greatGramps == null || !greatGramps.isVar()) {
        return null;
      }
      name = gramps.getString();
      break;
    case Token.ASSIGN:
      // ASSIGN (gramps)
      //   NAME|GETPROP
      //   OBJLIT (parent)
      //     STRING (n)
      Node lvalue = gramps.getFirstChild();
      name = lvalue.getQualifiedName();
      break;
    case Token.STRING_KEY:
      // OBJLIT
      //   STRING (gramps)
      //     OBJLIT (parent)
      //       STRING (n)
      if (greatGramps != null &&
          greatGramps.isObjectLit()) {
        name = getNameForObjLitKey(gramps);
      } else {
        return null;
      }
      break;
    default:
      return null;
  }
  if (name != null) {
    String key = n.getString();
    if (TokenStream.isJSIdentifier(key)) {
      return name + '.' + key;
    }
  }
  return null;
}
 
Example 17
Source File: Nopol2017_0014_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the fully qualified name corresponding to an object literal key,
 * as long as it and its prefix property names are valid JavaScript
 * identifiers. The object literal may be nested inside of other object
 * literals.
 *
 * For example, if called with node {@code n} representing "z" in any of
 * the following expressions, the result would be "w.x.y.z":
 * <code> var w = {x: {y: {z: 0}}}; </code>
 * <code> w.x = {y: {z: 0}}; </code>
 * <code> w.x.y = {'a': 0, 'z': 0}; </code>
 *
 * @param n A child of an OBJLIT node
 * @return The global name, or null if {@code n} doesn't correspond to the
 *   key of an object literal that can be named
 */
String getNameForObjLitKey(Node n) {
  Node parent = n.getParent();
  Preconditions.checkState(parent.isObjectLit());

  Node gramps = parent.getParent();
  if (gramps == null) {
    return null;
  }

  Node greatGramps = gramps.getParent();
  String name;
  switch (gramps.getType()) {
    case Token.NAME:
      // VAR
      //   NAME (gramps)
      //     OBJLIT (parent)
      //       STRING (n)
      if (greatGramps == null || !greatGramps.isVar()) {
        return null;
      }
      name = gramps.getString();
      break;
    case Token.ASSIGN:
      // ASSIGN (gramps)
      //   NAME|GETPROP
      //   OBJLIT (parent)
      //     STRING (n)
      Node lvalue = gramps.getFirstChild();
      name = lvalue.getQualifiedName();
      break;
    case Token.STRING_KEY:
      // OBJLIT
      //   STRING (gramps)
      //     OBJLIT (parent)
      //       STRING (n)
      if (greatGramps != null &&
          greatGramps.isObjectLit()) {
        name = getNameForObjLitKey(gramps);
      } else {
        return null;
      }
      break;
    default:
      return null;
  }
  if (name != null) {
    String key = n.getString();
    if (TokenStream.isJSIdentifier(key)) {
      return name + '.' + key;
    }
  }
  return null;
}
 
Example 18
Source File: Closure_130_CollapseProperties_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Declares global variables to serve as aliases for the values in an object
 * literal, optionally removing all of the object literal's keys and values.
 *
 * @param alias The object literal's flattened name (e.g. "a$b$c")
 * @param objlit The OBJLIT node
 * @param varNode The VAR node to which new global variables should be added
 *     as children
 * @param nameToAddAfter The child of {@code varNode} after which new
 *     variables should be added (may be null)
 * @param varParent {@code varNode}'s parent
 * @return The number of variables added
 */
private int declareVarsForObjLitValues(
    Name objlitName, String alias, Node objlit, Node varNode,
    Node nameToAddAfter, Node varParent) {
  int numVars = 0;
  int arbitraryNameCounter = 0;
  boolean discardKeys = !objlitName.shouldKeepKeys();

  for (Node key = objlit.getFirstChild(), nextKey; key != null;
       key = nextKey) {
    Node value = key.getFirstChild();
    nextKey = key.getNext();

    // A get or a set can not be rewritten as a VAR.
    if (key.isGetterDef() || key.isSetterDef()) {
      continue;
    }

    // We generate arbitrary names for keys that aren't valid JavaScript
    // identifiers, since those keys are never referenced. (If they were,
    // this object literal's child names wouldn't be collapsible.) The only
    // reason that we don't eliminate them entirely is the off chance that
    // their values are expressions that have side effects.
    boolean isJsIdentifier = !key.isNumber() &&
                             TokenStream.isJSIdentifier(key.getString());
    String propName = isJsIdentifier ?
        key.getString() : String.valueOf(++arbitraryNameCounter);

    // If the name cannot be collapsed, skip it.
    String qName = objlitName.getFullName() + '.' + propName;
    Name p = nameMap.get(qName);
    if (p != null && !p.canCollapse()) {
      continue;
    }

    String propAlias = appendPropForAlias(alias, propName);
    Node refNode = null;
    if (discardKeys) {
      objlit.removeChild(key);
      value.detachFromParent();
    } else {
      // Substitute a reference for the value.
      refNode = IR.name(propAlias);
      if (key.getBooleanProp(Node.IS_CONSTANT_NAME)) {
        refNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
      }

      key.replaceChild(value, refNode);
    }

    // Declare the collapsed name as a variable with the original value.
    Node nameNode = IR.name(propAlias);
    nameNode.addChildToFront(value);
    if (key.getBooleanProp(Node.IS_CONSTANT_NAME)) {
      nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    }
    Node newVar = IR.var(nameNode)
        .copyInformationFromForTree(key);
    if (nameToAddAfter != null) {
      varParent.addChildAfter(newVar, nameToAddAfter);
    } else {
      varParent.addChildBefore(newVar, varNode);
    }
    compiler.reportCodeChange();
    nameToAddAfter = newVar;

    // Update the global name's node ancestry if it hasn't already been
    // done. (Duplicate keys in an object literal can bring us here twice
    // for the same global name.)
    if (isJsIdentifier && p != null) {
      if (!discardKeys) {
        Ref newAlias =
            p.getDeclaration().cloneAndReclassify(Ref.Type.ALIASING_GET);
        newAlias.node = refNode;
        p.addRef(newAlias);
      }

      p.getDeclaration().node = nameNode;

      if (value.isFunction()) {
        checkForHosedThisReferences(value, value.getJSDocInfo(), p);
      }
    }

    numVars++;
  }
  return numVars;
}
 
Example 19
Source File: Closure_130_CollapseProperties_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Declares global variables to serve as aliases for the values in an object
 * literal, optionally removing all of the object literal's keys and values.
 *
 * @param alias The object literal's flattened name (e.g. "a$b$c")
 * @param objlit The OBJLIT node
 * @param varNode The VAR node to which new global variables should be added
 *     as children
 * @param nameToAddAfter The child of {@code varNode} after which new
 *     variables should be added (may be null)
 * @param varParent {@code varNode}'s parent
 * @return The number of variables added
 */
private int declareVarsForObjLitValues(
    Name objlitName, String alias, Node objlit, Node varNode,
    Node nameToAddAfter, Node varParent) {
  int numVars = 0;
  int arbitraryNameCounter = 0;
  boolean discardKeys = !objlitName.shouldKeepKeys();

  for (Node key = objlit.getFirstChild(), nextKey; key != null;
       key = nextKey) {
    Node value = key.getFirstChild();
    nextKey = key.getNext();

    // A get or a set can not be rewritten as a VAR.
    if (key.isGetterDef() || key.isSetterDef()) {
      continue;
    }

    // We generate arbitrary names for keys that aren't valid JavaScript
    // identifiers, since those keys are never referenced. (If they were,
    // this object literal's child names wouldn't be collapsible.) The only
    // reason that we don't eliminate them entirely is the off chance that
    // their values are expressions that have side effects.
    boolean isJsIdentifier = !key.isNumber() &&
                             TokenStream.isJSIdentifier(key.getString());
    String propName = isJsIdentifier ?
        key.getString() : String.valueOf(++arbitraryNameCounter);

    // If the name cannot be collapsed, skip it.
    String qName = objlitName.getFullName() + '.' + propName;
    Name p = nameMap.get(qName);
    if (p != null && !p.canCollapse()) {
      continue;
    }

    String propAlias = appendPropForAlias(alias, propName);
    Node refNode = null;
    if (discardKeys) {
      objlit.removeChild(key);
      value.detachFromParent();
    } else {
      // Substitute a reference for the value.
      refNode = IR.name(propAlias);
      if (key.getBooleanProp(Node.IS_CONSTANT_NAME)) {
        refNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
      }

      key.replaceChild(value, refNode);
    }

    // Declare the collapsed name as a variable with the original value.
    Node nameNode = IR.name(propAlias);
    nameNode.addChildToFront(value);
    if (key.getBooleanProp(Node.IS_CONSTANT_NAME)) {
      nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    }
    Node newVar = IR.var(nameNode)
        .copyInformationFromForTree(key);
    if (nameToAddAfter != null) {
      varParent.addChildAfter(newVar, nameToAddAfter);
    } else {
      varParent.addChildBefore(newVar, varNode);
    }
    compiler.reportCodeChange();
    nameToAddAfter = newVar;

    // Update the global name's node ancestry if it hasn't already been
    // done. (Duplicate keys in an object literal can bring us here twice
    // for the same global name.)
    if (isJsIdentifier && p != null) {
      if (!discardKeys) {
        Ref newAlias =
            p.getDeclaration().cloneAndReclassify(Ref.Type.ALIASING_GET);
        newAlias.node = refNode;
        p.addRef(newAlias);
      }

      p.getDeclaration().node = nameNode;

      if (value.isFunction()) {
        checkForHosedThisReferences(value, value.getJSDocInfo(), p);
      }
    }

    numVars++;
  }
  return numVars;
}
 
Example 20
Source File: Closure_89_CollapseProperties_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Declares global variables to serve as aliases for the values in an object
 * literal, optionally removing all of the object literal's keys and values.
 *
 * @param alias The object literal's flattened name (e.g. "a$b$c")
 * @param objlit The OBJLIT node
 * @param varNode The VAR node to which new global variables should be added
 *     as children
 * @param nameToAddAfter The child of {@code varNode} after which new
 *     variables should be added (may be null)
 * @param varParent {@code varNode}'s parent
 * @return The number of variables added
 */
private int declareVarsForObjLitValues(
    Name objlitName, String alias, Node objlit, Node varNode,
    Node nameToAddAfter, Node varParent) {
  int numVars = 0;
  int arbitraryNameCounter = 0;
  boolean discardKeys = !objlitName.shouldKeepKeys();

  for (Node key = objlit.getFirstChild(), nextKey; key != null;
       key = nextKey) {
    Node value = key.getFirstChild();
    nextKey = key.getNext();

    // We generate arbitrary names for keys that aren't valid JavaScript
    // identifiers, since those keys are never referenced. (If they were,
    // this object literal's child names wouldn't be collapsible.) The only
    // reason that we don't eliminate them entirely is the off chance that
    // their values are expressions that have side effects.
    boolean isJsIdentifier = key.getType() != Token.NUMBER &&
                             TokenStream.isJSIdentifier(key.getString());
    String propName = isJsIdentifier ?
        key.getString() : String.valueOf(++arbitraryNameCounter);
    String propAlias = appendPropForAlias(alias, propName);
    String qName = objlitName.fullName() + '.' + propName;

    Node refNode = null;
    if (discardKeys) {
      objlit.removeChild(key);
      value.detachFromParent();
    } else {
      // Substitute a reference for the value.
      refNode = Node.newString(Token.NAME, propAlias);
      if (key.getBooleanProp(Node.IS_CONSTANT_NAME)) {
        refNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
      }

      key.replaceChild(value, refNode);
    }

    // Declare the collapsed name as a variable with the original value.
    Node nameNode = Node.newString(Token.NAME, propAlias);
    nameNode.addChildToFront(value);
    if (key.getBooleanProp(Node.IS_CONSTANT_NAME)) {
      nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    }
    Node newVar = new Node(Token.VAR, nameNode)
        .copyInformationFromForTree(key);
    if (nameToAddAfter != null) {
      varParent.addChildAfter(newVar, nameToAddAfter);
    } else {
      varParent.addChildBefore(newVar, varNode);
    }
    compiler.reportCodeChange();
    nameToAddAfter = newVar;

    if (isJsIdentifier) {
      // Update the global name's node ancestry if it hasn't already been
      // done. (Duplicate keys in an object literal can bring us here twice
      // for the same global name.)
      Name p = nameMap.get(qName);
      if (p != null) {
        if (!discardKeys) {
          Ref newAlias =
              p.declaration.cloneAndReclassify(Ref.Type.ALIASING_GET);
          newAlias.node = refNode;
          p.addRef(newAlias);
        }

        p.declaration.node = nameNode;

        if (value.getType() == Token.FUNCTION) {
          checkForHosedThisReferences(value, value.getJSDocInfo(), p);
        }
      }
    }

    numVars++;
  }
  return numVars;
}