Java Code Examples for com.google.javascript.rhino.Node#isObjectLit()

The following examples show how to use com.google.javascript.rhino.Node#isObjectLit() . 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: Closure_113_ProcessClosurePrimitives_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * @return Whether the node is namespace placeholder.
 */
private static boolean isNamespacePlaceholder(Node n) {
  if (!n.getBooleanProp(Node.IS_NAMESPACE)) {
    return false;
  }

  Node value = null;
  if (n.isExprResult()) {
    Node assign = n.getFirstChild();
    value = assign.getLastChild();
  } else if (n.isVar()) {
    Node name = n.getFirstChild();
    value = name.getFirstChild();
  }

  return value != null
    && value.isObjectLit()
    && !value.hasChildren();
}
 
Example 2
Source File: Closure_113_ProcessClosurePrimitives_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * Verifies that setCssNameMapping is called with the correct methods.
 *
 * @return Whether the arguments checked out okay
 */
private boolean verifySetCssNameMapping(NodeTraversal t, Node methodName,
    Node firstArg) {
  DiagnosticType diagnostic = null;
  if (firstArg == null) {
    diagnostic = NULL_ARGUMENT_ERROR;
  } else if (!firstArg.isObjectLit()) {
    diagnostic = EXPECTED_OBJECTLIT_ERROR;
  } else if (firstArg.getNext() != null) {
    Node secondArg = firstArg.getNext();
    if (!secondArg.isString()) {
      diagnostic = EXPECTED_STRING_ERROR;
    } else if (secondArg.getNext() != null) {
      diagnostic = TOO_MANY_ARGUMENTS_ERROR;
    }
  }
  if (diagnostic != null) {
    compiler.report(
        t.makeError(methodName,
            diagnostic, methodName.getQualifiedName()));
    return false;
  }
  return true;
}
 
Example 3
Source File: Nopol2017_0010_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * Verifies that setCssNameMapping is called with the correct methods.
 *
 * @return Whether the arguments checked out okay
 */
private boolean verifySetCssNameMapping(NodeTraversal t, Node methodName,
    Node firstArg) {
  DiagnosticType diagnostic = null;
  if (firstArg == null) {
    diagnostic = NULL_ARGUMENT_ERROR;
  } else if (!firstArg.isObjectLit()) {
    diagnostic = EXPECTED_OBJECTLIT_ERROR;
  } else if (firstArg.getNext() != null) {
    Node secondArg = firstArg.getNext();
    if (!secondArg.isString()) {
      diagnostic = EXPECTED_STRING_ERROR;
    } else if (secondArg.getNext() != null) {
      diagnostic = TOO_MANY_ARGUMENTS_ERROR;
    }
  }
  if (diagnostic != null) {
    compiler.report(
        t.makeError(methodName,
            diagnostic, methodName.getQualifiedName()));
    return false;
  }
  return true;
}
 
Example 4
Source File: Nopol2017_0010_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * @return Whether the node is namespace placeholder.
 */
private static boolean isNamespacePlaceholder(Node n) {
  if (!n.getBooleanProp(Node.IS_NAMESPACE)) {
    return false;
  }

  Node value = null;
  if (n.isExprResult()) {
    Node assign = n.getFirstChild();
    value = assign.getLastChild();
  } else if (n.isVar()) {
    Node name = n.getFirstChild();
    value = name.getFirstChild();
  }

  return value != null
    && value.isObjectLit()
    && !value.hasChildren();
}
 
Example 5
Source File: Nopol2017_0010_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Verifies that setCssNameMapping is called with the correct methods.
 *
 * @return Whether the arguments checked out okay
 */
private boolean verifySetCssNameMapping(NodeTraversal t, Node methodName,
    Node firstArg) {
  DiagnosticType diagnostic = null;
  if (firstArg == null) {
    diagnostic = NULL_ARGUMENT_ERROR;
  } else if (!firstArg.isObjectLit()) {
    diagnostic = EXPECTED_OBJECTLIT_ERROR;
  } else if (firstArg.getNext() != null) {
    Node secondArg = firstArg.getNext();
    if (!secondArg.isString()) {
      diagnostic = EXPECTED_STRING_ERROR;
    } else if (secondArg.getNext() != null) {
      diagnostic = TOO_MANY_ARGUMENTS_ERROR;
    }
  }
  if (diagnostic != null) {
    compiler.report(
        t.makeError(methodName,
            diagnostic, methodName.getQualifiedName()));
    return false;
  }
  return true;
}
 
Example 6
Source File: Nopol2017_0010_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * @return Whether the node is namespace placeholder.
 */
private static boolean isNamespacePlaceholder(Node n) {
  if (!n.getBooleanProp(Node.IS_NAMESPACE)) {
    return false;
  }

  Node value = null;
  if (n.isExprResult()) {
    Node assign = n.getFirstChild();
    value = assign.getLastChild();
  } else if (n.isVar()) {
    Node name = n.getFirstChild();
    value = name.getFirstChild();
  }

  return value != null
    && value.isObjectLit()
    && !value.hasChildren();
}
 
Example 7
Source File: ClosureCodingConvention.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
@Override
public ObjectLiteralCast getObjectLiteralCast(Node callNode) {
  Preconditions.checkArgument(callNode.isCall());
  ObjectLiteralCast proxyCast = super.getObjectLiteralCast(callNode);
  if (proxyCast != null) {
    return proxyCast;
  }

  Node callName = callNode.getFirstChild();
  if (!"goog.reflect.object".equals(callName.getQualifiedName()) ||
      callNode.getChildCount() != 3) {
    return null;
  }

  Node typeNode = callName.getNext();
  if (!typeNode.isQualifiedName()) {
    return null;
  }

  Node objectNode = typeNode.getNext();
  if (!objectNode.isObjectLit()) {
    return new ObjectLiteralCast(null, null, OBJECTLIT_EXPECTED);
  }

  return new ObjectLiteralCast(
      typeNode.getQualifiedName(), typeNode.getNext(), null);
}
 
Example 8
Source File: Closure_23_PeepholeFoldConstants_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Try to fold array-element. e.g [1, 2, 3][10];
 */
private Node tryFoldGetElem(Node n, Node left, Node right) {
  Preconditions.checkArgument(n.isGetElem());

  if (left.isObjectLit()) {
    return tryFoldObjectPropAccess(n, left, right);
  }

  if (left.isArrayLit()) {
    return tryFoldArrayAccess(n, left, right);
  }
  return n;
}
 
Example 9
Source File: Closure_48_TypedScopeCreator_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.isFunction() &&
      shouldUseFunctionLiteralType(
          JSType.toMaybeFunctionType(rValue.getJSType()), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.isObjectLit()) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            return rValue.getJSType();
          } else if (rValue.isOr()) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.isName()
                && lValue.isName()
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 10
Source File: Closure_29_InlineObjectLiterals_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Counts the number of direct (full) references to an object.
 * Specifically we check for references of the following type:
 * <pre>
 *   x;
 *   x.fn();
 * </pre>
 */
private boolean isInlinableObject(List<Reference> refs) {
  boolean ret = false;
  for (Reference ref : refs) {
    Node name = ref.getNode();
    Node parent = ref.getParent();
    Node gramps = ref.getGrandparent();

    // Ignore indirect references, like x.y (except x.y(), since
    // the function referenced by y might reference 'this').
    //
    if (parent.isGetProp()) {
      Preconditions.checkState(parent.getFirstChild() == name);
      // A call target maybe using the object as a 'this' value.
      if (gramps.isCall()
          && gramps.getFirstChild() == parent) {
        return false;
      }

      // NOTE(nicksantos): This pass's object-splitting algorithm has
      // a blind spot. It assumes that if a property isn't defined on an
      // object, then the value is undefined. This is not true, because
      // Object.prototype can have arbitrary properties on it.
      //
      // We short-circuit this problem by bailing out if we see a reference
      // to a property that isn't defined on the object literal. This
      // isn't a perfect algorithm, but it should catch most cases.
      continue;
    }

    // Only rewrite VAR declarations or simple assignment statements
    if (!isVarOrAssignExprLhs(name)) {
       return false;
    }

    Node val = ref.getAssignedValue();
    if (val == null) {
      // A var with no assignment.
      continue;
    }

    // We're looking for object literal assignments only.
    if (!val.isObjectLit()) {
      return false;
    }

    // Make sure that the value is not self-refential. IOW,
    // disallow things like x = {b: x.a}.
    //
    // TODO: Only exclude unorderable self-referential
    // assignments. i.e. x = {a: x.b, b: x.a} is not orderable,
    // but x = {a: 1, b: x.a} is.
    //
    // Also, ES5 getters/setters aren't handled by this pass.
    for (Node child = val.getFirstChild(); child != null;
         child = child.getNext()) {
      if (child.isGetterDef() ||
          child.isSetterDef()) {
        // ES5 get/set not supported.
        return false;
      }


      Node childVal = child.getFirstChild();
      // Check if childVal is the parent of any of the passed in
      // references, as that is how self-referential assignments
      // will happen.
      for (Reference t : refs) {
        Node refNode = t.getParent();
        while (!NodeUtil.isStatementBlock(refNode)) {
          if (refNode == childVal) {
            // There's a self-referential assignment
            return false;
          }
          refNode = refNode.getParent();
        }
      }
    }


    // We have found an acceptable object literal assignment. As
    // long as there are no other assignments that mess things up,
    // we can inline.
    ret = true;
  }
  return ret;
}
 
Example 11
Source File: Closure_23_PeepholeFoldConstants_s.java    From coming with MIT License 4 votes vote down vote up
private Node tryFoldObjectPropAccess(Node n, Node left, Node right) {
  Preconditions.checkArgument(NodeUtil.isGet(n));

  if (!left.isObjectLit() || !right.isString()) {
    return n;
  }

  if (isAssignmentTarget(n)) {
    // If GETPROP/GETELEM is used as assignment target the object literal is
    // acting as a temporary we can't fold it here:
    //    "{a:x}.a += 1" is not "x += 1"
    return n;
  }

  // find the last definition in the object literal
  Node key = null;
  Node value = null;
  for (Node c = left.getFirstChild(); c != null; c = c.getNext()) {
    if (c.getString().equals(right.getString())) {
      switch (c.getType()) {
        case Token.SETTER_DEF:
          continue;
        case Token.GETTER_DEF:
        case Token.STRING_KEY:
          if (value != null && mayHaveSideEffects(value)) {
            // The previously found value had side-effects
            return n;
          }
          key = c;
          value = key.getFirstChild();
          break;
        default:
          throw new IllegalStateException();
      }
    } else if (mayHaveSideEffects(c.getFirstChild())) {
      // We don't handle the side-effects here as they might need a temporary
      // or need to be reordered.
      return n;
    }
  }

  // Didn't find a definition of the name in the object literal, it might
  // be coming from the Object prototype
  if (value == null) {
    return n;
  }

  if (value.isFunction() && NodeUtil.referencesThis(value)) {
    // 'this' may refer to the object we are trying to remove
    return n;
  }

  Node replacement = value.detachFromParent();
  if (key.isGetterDef()){
    replacement = IR.call(replacement);
    replacement.putBooleanProp(Node.FREE_CALL, true);
  }

  n.getParent().replaceChild(n, replacement);
  reportCodeChange();
  return n;
}
 
Example 12
Source File: Closure_119_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.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 13
Source File: Closure_17_TypedScopeCreator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.isFunction() &&
      shouldUseFunctionLiteralType(
          JSType.toMaybeFunctionType(rValue.getJSType()), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.isObjectLit()) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          JSDocInfo rValueInfo = rValue.getJSDocInfo();
          if (rValueInfo != null && rValueInfo.hasType()) {
            // If rValue has a type-cast, we use the type in the type-cast.
            return rValueInfo.getType().evaluate(scope, typeRegistry);
          } else if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            // If rValue's type was already computed during scope creation,
            // then we can safely use that.
            return rValue.getJSType();
          } else if (rValue.isOr()) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.isName()
                && lValue.isName()
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 14
Source File: PeepholeFoldConstants.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
private Node tryFoldObjectPropAccess(Node n, Node left, Node right) {
  Preconditions.checkArgument(NodeUtil.isGet(n));

  if (!left.isObjectLit() || !right.isString()) {
    return n;
  }

  if (isAssignmentTarget(n)) {
    // If GETPROP/GETELEM is used as assignment target the object literal is
    // acting as a temporary we can't fold it here:
    //    "{a:x}.a += 1" is not "x += 1"
    return n;
  }

  // find the last definition in the object literal
  Node key = null;
  Node value = null;
  for (Node c = left.getFirstChild(); c != null; c = c.getNext()) {
    if (c.getString().equals(right.getString())) {
      switch (c.getType()) {
        case Token.SETTER_DEF:
          continue;
        case Token.GETTER_DEF:
        case Token.STRING_KEY:
          if (value != null && mayHaveSideEffects(value)) {
            // The previously found value had side-effects
            return n;
          }
          key = c;
          value = key.getFirstChild();
          break;
        default:
          throw new IllegalStateException();
      }
    } else if (mayHaveSideEffects(c.getFirstChild())) {
      // We don't handle the side-effects here as they might need a temporary
      // or need to be reordered.
      return n;
    }
  }

  // Didn't find a definition of the name in the object literal, it might
  // be coming from the Object prototype
  if (value == null) {
    return n;
  }

  if (value.isFunction() && NodeUtil.referencesThis(value)) {
    // 'this' may refer to the object we are trying to remove
    return n;
  }

  Node replacement = value.detachFromParent();
  if (key.isGetterDef()){
    replacement = IR.call(replacement);
    replacement.putBooleanProp(Node.FREE_CALL, true);
  }

  n.getParent().replaceChild(n, replacement);
  reportCodeChange();
  return n;
}
 
Example 15
Source File: Closure_119_GlobalNamespace_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 16
Source File: AnalyzePrototypeProperties.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  if (n.isGetProp()) {
    String propName = n.getFirstChild().getNext().getString();

    if (n.isQualifiedName()) {
      if (propName.equals("prototype")) {
        if (processPrototypeRef(t, n)) {
          return;
        }
      } else if (compiler.getCodingConvention().isExported(propName)) {
        addGlobalUseOfSymbol(propName, t.getModule(), PROPERTY);
        return;
      } else {
        // Do not mark prototype prop assigns as a 'use' in the global scope.
        if (n.getParent().isAssign() && n.getNext() != null) {
          String rValueName = getPrototypePropertyNameFromRValue(n);
          if (rValueName != null) {
            return;
          }
        }
      }
    }

    addSymbolUse(propName, t.getModule(), PROPERTY);
  } else if (n.isObjectLit()) {
    // Make sure that we're not handling object literals being
    // assigned to a prototype, as in:
    // Foo.prototype = {bar: 3, baz: 5};
    String lValueName = NodeUtil.getBestLValueName(
        NodeUtil.getBestLValue(n));
    if (lValueName != null && lValueName.endsWith(".prototype")) {
      return;
    }

    // var x = {a: 1, b: 2}
    // should count as a use of property a and b.
    for (Node propNameNode = n.getFirstChild(); propNameNode != null;
         propNameNode = propNameNode.getNext()) {
      // May be STRING, GET, or SET, but NUMBER isn't interesting.
      if (!propNameNode.isQuotedString()) {
        addSymbolUse(propNameNode.getString(), t.getModule(), PROPERTY);
      }
    }
  } else if (n.isName()) {
    String name = n.getString();

    Var var = t.getScope().getVar(name);
    if (var != null) {
      // Only process global functions.
      if (var.isGlobal()) {
        if (var.getInitialValue() != null &&
            var.getInitialValue().isFunction()) {
          if (t.inGlobalScope()) {
            if (!processGlobalFunctionDeclaration(t, n, var)) {
              addGlobalUseOfSymbol(name, t.getModule(), VAR);
            }
          } else {
            addSymbolUse(name, t.getModule(), VAR);
          }
        }

      // If it is not a global, it might be accessing a local of the outer
      // scope. If that's the case the functions between the variable's
      // declaring scope and the variable reference scope cannot be moved.
      } else if (var.getScope() != t.getScope()){
        for (int i = symbolStack.size() - 1; i >= 0; i--) {
          NameContext context = symbolStack.get(i);
          if (context.scope == var.getScope()) {
            break;
          }

          context.name.readClosureVariables = true;
        }
      }
    }
  }

  // Process prototype assignments to non-functions.
  if (processNonFunctionPrototypeAssign(n, parent) != null) {
    symbolStack.pop();
  }
}
 
Example 17
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 18
Source File: Closure_43_TypedScopeCreator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.isFunction() &&
      shouldUseFunctionLiteralType(
          JSType.toMaybeFunctionType(rValue.getJSType()), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.isObjectLit()) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            return rValue.getJSType();
          } else if (rValue.isOr()) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.isName()
                && lValue.isName()
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 19
Source File: Closure_119_GlobalNamespace_s.java    From coming with MIT License 3 votes vote down vote up
/**
 * Determines whether a set operation is a constructor or enumeration
 * or interface declaration. The set operation may either be an assignment
 * to a name, a variable declaration, or an object literal key mapping.
 *
 * @param n The node that represents the name being set
 * @param parent Parent node of {@code n} (an ASSIGN, VAR, or OBJLIT node)
 * @return Whether the set operation is either a constructor or enum
 *     declaration
 */
private boolean isTypeDeclaration(Node n, Node parent) {
  Node valueNode = NodeUtil.getRValueOfLValue(n);
  JSDocInfo info = NodeUtil.getBestJSDocInfo(n);
  // Heed the annotations only if they're sensibly used.
  return info != null && valueNode != null &&
         (info.isConstructor() && valueNode.isFunction() ||
          info.isInterface() && valueNode.isFunction() ||
          info.hasEnumParameterType() && valueNode.isObjectLit());
}
 
Example 20
Source File: GentsNodeUtil.java    From clutz with MIT License 3 votes vote down vote up
/**
 * Returns true is the object is an object literal where all values are simple symbols references:
 *
 * <p>{A, B, C} -> true
 *
 * <p>{A, B: B} -> true
 *
 * <p>{A: C} -> true
 *
 * <p>{A: A + 1} -> false
 *
 * <p>{A: f(1)} -> false
 */
public static boolean isObjLitWithSimpleRefs(Node node) {
  if (!node.isObjectLit()) return false;
  for (Node child : node.children()) {
    if (!child.isStringKey() || !child.getFirstChild().isName()) {
      return false;
    }
  }
  return true;
}