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

The following examples show how to use com.google.javascript.rhino.Node#getJSType() . 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_19_ChainableReverseAbstractInterpreter_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * Declares a refined type in {@code scope} for the name represented by
 * {@code node}. It must be possible to refine the type of the given node in
 * the given scope, as determined by {@link #getTypeIfRefinable}.
 */
protected void declareNameInScope(FlowScope scope, Node node, JSType type) {
  switch (node.getType()) {
    case Token.NAME:
      scope.inferSlotType(node.getString(), type);
      break;

    case Token.GETPROP:
      String qualifiedName = node.getQualifiedName();
      Preconditions.checkNotNull(qualifiedName);

      JSType origType = node.getJSType();
      origType = origType == null ? getNativeType(UNKNOWN_TYPE) : origType;
      scope.inferQualifiedSlot(node, qualifiedName, origType, type);
      break;

      // "this" references aren't currently modeled in the CFG.

    default:
      throw new IllegalArgumentException("Node cannot be refined. \n" +
          node.toStringTree());
  }
}
 
Example 2
Source File: Closure_66_TypeCheck_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * Enforces type casts, and ensures the node is typed.
 *
 * A cast in the way that we use it in JSDoc annotations never
 * alters the generated code and therefore never can induce any runtime
 * operation. What this means is that a 'cast' is really just a compile
 * time constraint on the underlying value. In the future, we may add
 * support for run-time casts for compiled tests.
 *
 * To ensure some shred of sanity, we enforce the notion that the
 * type you are casting to may only meaningfully be a narrower type
 * than the underlying declared type. We also invalidate optimizations
 * on bad type casts.
 *
 * @param t The traversal object needed to report errors.
 * @param n The node getting a type assigned to it.
 * @param type The type to be assigned.
 */
private void ensureTyped(NodeTraversal t, Node n, JSType type) {
  // Make sure FUNCTION nodes always get function type.
  Preconditions.checkState(n.getType() != Token.FUNCTION ||
          type instanceof FunctionType ||
          type.isUnknownType());
  JSDocInfo info = n.getJSDocInfo();
  if (info != null) {
    if (info.hasType()) {
      JSType infoType = info.getType().evaluate(t.getScope(), typeRegistry);
      validator.expectCanCast(t, n, infoType, type);
      type = infoType;
    }

    if (info.isImplicitCast() && !inExterns) {
      String propName = n.getType() == Token.GETPROP ?
          n.getLastChild().getString() : "(missing)";
      compiler.report(
          t.makeError(n, ILLEGAL_IMPLICIT_CAST, propName));
    }
  }

  if (n.getJSType() == null) {
    n.setJSType(type);
  }
}
 
Example 3
Source File: Closure_70_TypedScopeCreator_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * Declares all of a function's arguments.
 */
private void declareArguments(Node functionNode) {
  Node astParameters = functionNode.getFirstChild().getNext();
  Node body = astParameters.getNext();
  FunctionType functionType = (FunctionType) functionNode.getJSType();
  if (functionType != null) {
    Node jsDocParameters = functionType.getParametersNode();
    if (jsDocParameters != null) {
      Node jsDocParameter = jsDocParameters.getFirstChild();
      for (Node astParameter : astParameters.children()) {
        if (jsDocParameter != null) {
          defineSlot(astParameter, functionNode,
              jsDocParameter.getJSType(), true);
          jsDocParameter = jsDocParameter.getNext();
        } else {
          defineSlot(astParameter, functionNode, null, true);
        }
      }
    }
  }
}
 
Example 4
Source File: TypedScopeCreatorTest.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
private JSType findTypeOnMatchedNode(Predicate<Node> matcher, Scope scope) {
  Node root = scope.getRootNode();
  Deque<Node> queue = Lists.newLinkedList();
  queue.push(root);
  while (!queue.isEmpty()) {
    Node current = queue.pop();
    if (matcher.apply(current) &&
        current.getJSType() != null) {
      return current.getJSType();
    }

    for (Node child : current.children()) {
      queue.push(child);
    }
  }
  return null;
}
 
Example 5
Source File: Closure_19_ChainableReverseAbstractInterpreter_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Declares a refined type in {@code scope} for the name represented by
 * {@code node}. It must be possible to refine the type of the given node in
 * the given scope, as determined by {@link #getTypeIfRefinable}.
 */
protected void declareNameInScope(FlowScope scope, Node node, JSType type) {
  switch (node.getType()) {
    case Token.NAME:
      scope.inferSlotType(node.getString(), type);
      break;

    case Token.GETPROP:
      String qualifiedName = node.getQualifiedName();
      Preconditions.checkNotNull(qualifiedName);

      JSType origType = node.getJSType();
      origType = origType == null ? getNativeType(UNKNOWN_TYPE) : origType;
      scope.inferQualifiedSlot(node, qualifiedName, origType, type);
      break;

    case Token.THIS:
      // "this" references aren't currently modeled in the CFG.
      break;

    default:
      throw new IllegalArgumentException("Node cannot be refined. \n" +
          node.toStringTree());
  }
}
 
Example 6
Source File: Nopol2017_0051_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * This method gets the JSType from the Node argument and verifies that it is
 * present.
 */
private JSType getJSType(Node n) {
  JSType jsType = n.getJSType();
  if (jsType == null) {
    // TODO(nicksantos): This branch indicates a compiler bug, not worthy of
    // halting the compilation but we should log this and analyze to track
    // down why it happens. This is not critical and will be resolved over
    // time as the type checker is extended.
    return getNativeType(UNKNOWN_TYPE);
  } else {
    return jsType;
  }
}
 
Example 7
Source File: SemanticReverseAbstractInterpreter.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Given 'property in object', ensures that the object has the property in the
 * informed scope by defining it as a qualified name if the object type lacks
 * the property and it's not in the blind scope.
 * @param object The node of the right-side of the in.
 * @param propertyName The string of the left-side of the in.
 */
private FlowScope caseIn(Node object, String propertyName, FlowScope blindScope) {
  JSType jsType = object.getJSType();
  jsType = this.getRestrictedWithoutNull(jsType);
  jsType = this.getRestrictedWithoutUndefined(jsType);

  boolean hasProperty = false;
  ObjectType objectType = ObjectType.cast(jsType);
  if (objectType != null) {
    hasProperty = objectType.hasProperty(propertyName);
  }
  if (!hasProperty) {
    String qualifiedName = object.getQualifiedName();
    if (qualifiedName != null) {
      String propertyQualifiedName = qualifiedName + "." + propertyName;
      if (blindScope.getSlot(propertyQualifiedName) == null) {
        FlowScope informed = blindScope.createChildFlowScope();
        JSType unknownType = typeRegistry.getNativeType(
            JSTypeNative.UNKNOWN_TYPE);
        informed.inferQualifiedSlot(
            object, propertyQualifiedName, unknownType, unknownType);
        return informed;
      }
    }
  }
  return blindScope;
}
 
Example 8
Source File: Closure_96_TypeCheck_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Visits a {@link Token#FUNCTION} node.
 *
 * @param t The node traversal object that supplies context, such as the
 * scope chain to use in name lookups as well as error reporting.
 * @param n The node being visited.
 */
private void visitFunction(NodeTraversal t, Node n) {
  JSDocInfo info = n.getJSDocInfo();

  FunctionType functionType = (FunctionType) n.getJSType();
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isInterface() || functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.
        getPrototype().getImplicitPrototype().getConstructor();
    if (baseConstructor != null &&
        baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        (baseConstructor.isConstructor() && functionType.isInterface() ||
         baseConstructor.isInterface() && functionType.isConstructor())) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE, functionPrivateName));
    }

    for (JSType baseInterface : functionType.getImplementedInterfaces()) {
      boolean badImplementedType = false;
      ObjectType baseInterfaceObj = ObjectType.cast(baseInterface);
      if (baseInterfaceObj != null) {
        FunctionType interfaceConstructor =
            baseInterfaceObj.getConstructor();
        if (interfaceConstructor != null &&
            !interfaceConstructor.isInterface()) {
          badImplementedType = true;
        }
      } else {
        badImplementedType = true;
      }
      if (badImplementedType) {
        report(t, n, BAD_IMPLEMENTED_TYPE, functionPrivateName);
      }
    }
    if (functionType.isConstructor()) {
      validator.expectAllInterfacePropertiesImplemented(functionType);
    }
  }
}
 
Example 9
Source File: Closure_125_TypeCheck_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Counts the given node in the typed statistics.
 * @param n a node that should be typed
 */
private void doPercentTypedAccounting(NodeTraversal t, Node n) {
  JSType type = n.getJSType();
  if (type == null) {
    nullCount++;
  } else if (type.isUnknownType()) {
    if (reportUnknownTypes) {
      compiler.report(t.makeError(n, UNKNOWN_EXPR_TYPE));
    }
    unknownCount++;
  } else {
    typedCount++;
  }
}
 
Example 10
Source File: Nopol2017_0029_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Visits a NAME node.
 *
 * @param t The node traversal object that supplies context, such as the
 * scope chain to use in name lookups as well as error reporting.
 * @param n The node being visited.
 * @param parent The parent of the node n.
 * @return whether the node is typeable or not
 */
boolean visitName(NodeTraversal t, Node n, Node parent) {
  // At this stage, we need to determine whether this is a leaf
  // node in an expression (which therefore needs to have a type
  // assigned for it) versus some other decorative node that we
  // can safely ignore.  Function names, arguments (children of LP nodes) and
  // variable declarations are ignored.
  // TODO(user): remove this short-circuiting in favor of a
  // pre order traversal of the FUNCTION, CATCH, LP and VAR nodes.
  int parentNodeType = parent.getType();
  if (parentNodeType == Token.FUNCTION ||
      parentNodeType == Token.CATCH ||
      parentNodeType == Token.PARAM_LIST ||
      parentNodeType == Token.VAR) {
    return false;
  }

  JSType type = n.getJSType();
  if (type == null) {
    type = getNativeType(UNKNOWN_TYPE);
    Var var = t.getScope().getVar(n.getString());
    if (var != null) {
      JSType varType = var.getType();
      if (varType != null) {
        type = varType;
      }
    }
  }
  ensureTyped(t, n, type);
  return true;
}
 
Example 11
Source File: Closure_25_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
private FlowScope traverseAdd(Node n, FlowScope scope) {
  Node left = n.getFirstChild();
  Node right = left.getNext();
  scope = traverseChildren(n, scope);

  JSType leftType = left.getJSType();
  JSType rightType = right.getJSType();

  JSType type = getNativeType(UNKNOWN_TYPE);
  if (leftType != null && rightType != null) {
    boolean leftIsUnknown = leftType.isUnknownType();
    boolean rightIsUnknown = rightType.isUnknownType();
    if (leftIsUnknown && rightIsUnknown) {
      type = getNativeType(UNKNOWN_TYPE);
    } else if ((!leftIsUnknown && leftType.isString()) ||
               (!rightIsUnknown && rightType.isString())) {
      type = getNativeType(STRING_TYPE);
    } else if (leftIsUnknown || rightIsUnknown) {
      type = getNativeType(UNKNOWN_TYPE);
    } else if (isAddedAsNumber(leftType) && isAddedAsNumber(rightType)) {
      type = getNativeType(NUMBER_TYPE);
    } else {
      type = registry.createUnionType(STRING_TYPE, NUMBER_TYPE);
    }
  }
  n.setJSType(type);

  if (n.isAssignAdd()) {
    updateScopeForTypeChange(scope, left, leftType, type);
  }

  return scope;
}
 
Example 12
Source File: Closure_35_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
private FlowScope traverseAdd(Node n, FlowScope scope) {
  Node left = n.getFirstChild();
  Node right = left.getNext();
  scope = traverseChildren(n, scope);

  JSType leftType = left.getJSType();
  JSType rightType = right.getJSType();

  JSType type = getNativeType(UNKNOWN_TYPE);
  if (leftType != null && rightType != null) {
    boolean leftIsUnknown = leftType.isUnknownType();
    boolean rightIsUnknown = rightType.isUnknownType();
    if (leftIsUnknown && rightIsUnknown) {
      type = getNativeType(UNKNOWN_TYPE);
    } else if ((!leftIsUnknown && leftType.isString()) ||
               (!rightIsUnknown && rightType.isString())) {
      type = getNativeType(STRING_TYPE);
    } else if (leftIsUnknown || rightIsUnknown) {
      type = getNativeType(UNKNOWN_TYPE);
    } else if (isAddedAsNumber(leftType) && isAddedAsNumber(rightType)) {
      type = getNativeType(NUMBER_TYPE);
    } else {
      type = registry.createUnionType(STRING_TYPE, NUMBER_TYPE);
    }
  }
  n.setJSType(type);

  if (n.isAssignAdd()) {
    updateScopeForTypeChange(scope, left, leftType, type);
  }

  return scope;
}
 
Example 13
Source File: Closure_11_TypeCheck_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * This method gets the JSType from the Node argument and verifies that it is
 * present.
 */
private JSType getJSType(Node n) {
  JSType jsType = n.getJSType();
  if (jsType == null) {
    // TODO(nicksantos): This branch indicates a compiler bug, not worthy of
    // halting the compilation but we should log this and analyze to track
    // down why it happens. This is not critical and will be resolved over
    // time as the type checker is extended.
    return getNativeType(UNKNOWN_TYPE);
  } else {
    return jsType;
  }
}
 
Example 14
Source File: Closure_125_TypeCheck_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Visits a NAME node.
 *
 * @param t The node traversal object that supplies context, such as the
 * scope chain to use in name lookups as well as error reporting.
 * @param n The node being visited.
 * @param parent The parent of the node n.
 * @return whether the node is typeable or not
 */
boolean visitName(NodeTraversal t, Node n, Node parent) {
  // At this stage, we need to determine whether this is a leaf
  // node in an expression (which therefore needs to have a type
  // assigned for it) versus some other decorative node that we
  // can safely ignore.  Function names, arguments (children of LP nodes) and
  // variable declarations are ignored.
  // TODO(user): remove this short-circuiting in favor of a
  // pre order traversal of the FUNCTION, CATCH, LP and VAR nodes.
  int parentNodeType = parent.getType();
  if (parentNodeType == Token.FUNCTION ||
      parentNodeType == Token.CATCH ||
      parentNodeType == Token.PARAM_LIST ||
      parentNodeType == Token.VAR) {
    return false;
  }

  JSType type = n.getJSType();
  if (type == null) {
    type = getNativeType(UNKNOWN_TYPE);
    Var var = t.getScope().getVar(n.getString());
    if (var != null) {
      JSType varType = var.getType();
      if (varType != null) {
        type = varType;
      }
    }
  }
  ensureTyped(t, n, type);
  return true;
}
 
Example 15
Source File: Closure_112_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * This method gets the JSType from the Node argument and verifies that it is
 * present.
 */
private JSType getJSType(Node n) {
  JSType jsType = n.getJSType();
  if (jsType == null) {
    // TODO(nicksantos): This branch indicates a compiler bug, not worthy of
    // halting the compilation but we should log this and analyze to track
    // down why it happens. This is not critical and will be resolved over
    // time as the type checker is extended.
    return unknownType;
  } else {
    return jsType;
  }
}
 
Example 16
Source File: Closure_7_ChainableReverseAbstractInterpreter_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Returns the type of a node in the given scope if the node corresponds to a
 * name whose type is capable of being refined.
 * @return The current type of the node if it can be refined, null otherwise.
 */
protected JSType getTypeIfRefinable(Node node, FlowScope scope) {
  switch (node.getType()) {
    case Token.NAME:
      StaticSlot<JSType> nameVar = scope.getSlot(node.getString());
      if (nameVar != null) {
        JSType nameVarType = nameVar.getType();
        if (nameVarType == null) {
          nameVarType = node.getJSType();
        }
        return nameVarType;
      }
      return null;

    case Token.GETPROP:
      String qualifiedName = node.getQualifiedName();
      if (qualifiedName == null) {
        return null;
      }
      StaticSlot<JSType> propVar = scope.getSlot(qualifiedName);
      JSType propVarType = null;
      if (propVar != null) {
        propVarType = propVar.getType();
      }
      if (propVarType == null) {
        propVarType = node.getJSType();
      }
      if (propVarType == null) {
        propVarType = getNativeType(UNKNOWN_TYPE);
      }
      return propVarType;
  }
  return null;
}
 
Example 17
Source File: ConcreteTypeTest.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public ConcreteFunctionType createConcreteFunction(
    Node decl, StaticScope<ConcreteType> parent) {
  ConcreteFunctionType funcType = functionByDeclaration.get(decl);
  if (funcType == null) {
    functionByDeclaration.put(decl, funcType =
        new ConcreteFunctionType(this, decl, parent));
    if (decl.getJSType() != null) {
      functionByJSType.put((FunctionType) decl.getJSType(), funcType);
    }
  }
  return funcType;
}
 
Example 18
Source File: Closure_11_TypeCheck_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Counts the given node in the typed statistics.
 * @param n a node that should be typed
 */
private void doPercentTypedAccounting(NodeTraversal t, Node n) {
  JSType type = n.getJSType();
  if (type == null) {
    nullCount++;
  } else if (type.isUnknownType()) {
    if (reportUnknownTypes.isOn()) {
      compiler.report(
          t.makeError(n, reportUnknownTypes, UNKNOWN_EXPR_TYPE));
    }
    unknownCount++;
  } else {
    typedCount++;
  }
}
 
Example 19
Source File: Closure_35_TypeInference_t.java    From coming with MIT License 4 votes vote down vote up
private FlowScope traverseObjectLiteral(Node n, FlowScope scope) {
  JSType type = n.getJSType();
  Preconditions.checkNotNull(type);

  for (Node name = n.getFirstChild(); name != null; name = name.getNext()) {
    scope = traverse(name.getFirstChild(), scope);
  }

  // Object literals can be reflected on other types, or changed with
  // type casts.
  // See CodingConvention#getObjectLiteralCase and goog.object.reflect.
  // Ignore these types of literals.
  // TODO(nicksantos): There should be an "anonymous object" type that
  // we can check for here.
  ObjectType objectType = ObjectType.cast(type);
  if (objectType == null) {
    return scope;
  }

  boolean hasLendsName = n.getJSDocInfo() != null &&
      n.getJSDocInfo().getLendsName() != null;
  if (objectType.hasReferenceName() && !hasLendsName) {
    return scope;
  }

  String qObjName = NodeUtil.getBestLValueName(
      NodeUtil.getBestLValue(n));
  for (Node name = n.getFirstChild(); name != null;
       name = name.getNext()) {
    Node value = name.getFirstChild();
    String memberName = NodeUtil.getObjectLitKeyName(name);
    if (memberName != null) {
      JSType rawValueType =  name.getFirstChild().getJSType();
      JSType valueType = NodeUtil.getObjectLitKeyTypeFromValueType(
          name, rawValueType);
      if (valueType == null) {
        valueType = getNativeType(UNKNOWN_TYPE);
      }
      objectType.defineInferredProperty(memberName, valueType, name);

      // Do normal flow inference if this is a direct property assignment.
      if (qObjName != null && name.isString()) {
        String qKeyName = qObjName + "." + memberName;
        Var var = syntacticScope.getVar(qKeyName);
        JSType oldType = var == null ? null : var.getType();
        if (var != null && var.isTypeInferred()) {
          var.setType(oldType == null ?
              valueType : oldType.getLeastSupertype(oldType));
        }

        scope.inferQualifiedSlot(name, qKeyName,
            oldType == null ? getNativeType(UNKNOWN_TYPE) : oldType,
            valueType);
      }
    } else {
      n.setJSType(getNativeType(UNKNOWN_TYPE));
    }
  }
  return scope;
}
 
Example 20
Source File: Closure_35_TypeInference_t.java    From coming with MIT License 4 votes vote down vote up
private BooleanOutcomePair traverseShortCircuitingBinOp(
    Node n, FlowScope scope, boolean condition) {
  Node left = n.getFirstChild();
  Node right = n.getLastChild();

  // type the left node
  BooleanOutcomePair leftLiterals =
      traverseWithinShortCircuitingBinOp(left,
          scope.createChildFlowScope());
  JSType leftType = left.getJSType();

  // reverse abstract interpret the left node to produce the correct
  // scope in which to verify the right node
  FlowScope rightScope = reverseInterpreter.
      getPreciserScopeKnowingConditionOutcome(
          left, leftLiterals.getOutcomeFlowScope(left.getType(), condition),
          condition);

  // type the right node
  BooleanOutcomePair rightLiterals =
      traverseWithinShortCircuitingBinOp(
          right, rightScope.createChildFlowScope());
  JSType rightType = right.getJSType();

  JSType type;
  BooleanOutcomePair literals;
  if (leftType != null && rightType != null) {
    leftType = leftType.getRestrictedTypeGivenToBooleanOutcome(!condition);
    if (leftLiterals.toBooleanOutcomes ==
        BooleanLiteralSet.get(!condition)) {
      // Use the restricted left type, since the right side never gets
      // evaluated.
      type = leftType;
      literals = leftLiterals;
    } else {
      // Use the join of the restricted left type knowing the outcome of the
      // ToBoolean predicate and of the right type.
      type = leftType.getLeastSupertype(rightType);
      literals =
          getBooleanOutcomePair(leftLiterals, rightLiterals, condition);
    }

    // Exclude the boolean type if the literal set is empty because a boolean
    // can never actually be returned.
    if (literals.booleanValues == BooleanLiteralSet.EMPTY &&
        getNativeType(BOOLEAN_TYPE).isSubtype(type)) {
      // Exclusion only make sense for a union type.
      if (type.isUnionType()) {
        type = type.toMaybeUnionType().getRestrictedUnion(
            getNativeType(BOOLEAN_TYPE));
      }
    }
  } else {
    type = null;
    literals = new BooleanOutcomePair(
        BooleanLiteralSet.BOTH, BooleanLiteralSet.BOTH,
        leftLiterals.getJoinedFlowScope(),
        rightLiterals.getJoinedFlowScope());
  }
  n.setJSType(type);

  return literals;
}