Java Code Examples for com.google.javascript.rhino.jstype.JSType#isEquivalentTo()

The following examples show how to use com.google.javascript.rhino.jstype.JSType#isEquivalentTo() . 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_112_TypeInference_s.java    From coming with MIT License 6 votes vote down vote up
private FlowScope traverseCall(Node n, FlowScope scope) {
  scope = traverseChildren(n, scope);

  Node left = n.getFirstChild();
  JSType functionType = getJSType(left).restrictByNotNullOrUndefined();
  if (functionType.isFunctionType()) {
    FunctionType fnType = functionType.toMaybeFunctionType();
    n.setJSType(fnType.getReturnType());
    backwardsInferenceFromCallSite(n, fnType);
  } else if (functionType.isEquivalentTo(
      getNativeType(CHECKED_UNKNOWN_TYPE))) {
    n.setJSType(getNativeType(CHECKED_UNKNOWN_TYPE));
  }

  scope = tightenTypesAfterAssertions(scope, n);
  return scope;
}
 
Example 2
Source File: TypeInference.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
private FlowScope traverseCall(Node n, FlowScope scope) {
  scope = traverseChildren(n, scope);

  Node left = n.getFirstChild();
  JSType functionType = getJSType(left).restrictByNotNullOrUndefined();
  if (functionType.isFunctionType()) {
    FunctionType fnType = functionType.toMaybeFunctionType();
    n.setJSType(fnType.getReturnType());
    backwardsInferenceFromCallSite(n, fnType);
  } else if (functionType.isEquivalentTo(
      getNativeType(CHECKED_UNKNOWN_TYPE))) {
    n.setJSType(getNativeType(CHECKED_UNKNOWN_TYPE));
  }

  scope = tightenTypesAfterAssertions(scope, n);
  return scope;
}
 
Example 3
Source File: Closure_112_TypeInference_t.java    From coming with MIT License 6 votes vote down vote up
private FlowScope traverseCall(Node n, FlowScope scope) {
  scope = traverseChildren(n, scope);

  Node left = n.getFirstChild();
  JSType functionType = getJSType(left).restrictByNotNullOrUndefined();
  if (functionType.isFunctionType()) {
    FunctionType fnType = functionType.toMaybeFunctionType();
    n.setJSType(fnType.getReturnType());
    backwardsInferenceFromCallSite(n, fnType);
  } else if (functionType.isEquivalentTo(
      getNativeType(CHECKED_UNKNOWN_TYPE))) {
    n.setJSType(getNativeType(CHECKED_UNKNOWN_TYPE));
  }

  scope = tightenTypesAfterAssertions(scope, n);
  return scope;
}
 
Example 4
Source File: Nopol2017_0029_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Emit a warning if we can prove that a property cannot possibly be
 * defined on an object. Note the difference between JS and a strictly
 * statically typed language: we're checking if the property
 * *cannot be defined*, whereas a java compiler would check if the
 * property *can be undefined*.
 */
private void checkPropertyAccess(JSType childType, String propName,
    NodeTraversal t, Node n) {
  // If the property type is unknown, check the object type to see if it
  // can ever be defined. We explicitly exclude CHECKED_UNKNOWN (for
  // properties where we've checked that it exists, or for properties on
  // objects that aren't in this binary).
  JSType propType = getJSType(n);
  if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
    childType = childType.autobox();
    ObjectType objectType = ObjectType.cast(childType);
    if (objectType != null) {
      // We special-case object types so that checks on enums can be
      // much stricter, and so that we can use hasProperty (which is much
      // faster in most cases).
      if (!objectType.hasProperty(propName) ||
          objectType.isEquivalentTo(
              typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        if (objectType instanceof EnumType) {
          report(t, n, INEXISTENT_ENUM_ELEMENT, propName);
        } else {
          checkPropertyAccessHelper(objectType, propName, t, n);
        }
      }

    } else {
      checkPropertyAccessHelper(childType, propName, t, n);
    }
  }
}
 
Example 5
Source File: Closure_11_TypeCheck_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Emit a warning if we can prove that a property cannot possibly be
 * defined on an object. Note the difference between JS and a strictly
 * statically typed language: we're checking if the property
 * *cannot be defined*, whereas a java compiler would check if the
 * property *can be undefined*.
 */
private void checkPropertyAccess(JSType childType, String propName,
    NodeTraversal t, Node n) {
  // If the property type is unknown, check the object type to see if it
  // can ever be defined. We explicitly exclude CHECKED_UNKNOWN (for
  // properties where we've checked that it exists, or for properties on
  // objects that aren't in this binary).
  JSType propType = getJSType(n);
  if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
    childType = childType.autobox();
    ObjectType objectType = ObjectType.cast(childType);
    if (objectType != null) {
      // We special-case object types so that checks on enums can be
      // much stricter, and so that we can use hasProperty (which is much
      // faster in most cases).
      if (!objectType.hasProperty(propName) ||
          objectType.isEquivalentTo(
              typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        if (objectType instanceof EnumType) {
          report(t, n, INEXISTENT_ENUM_ELEMENT, propName);
        } else {
          checkPropertyAccessHelper(objectType, propName, t, n);
        }
      }

    } else {
      checkPropertyAccessHelper(childType, propName, t, n);
    }
  }
}
 
Example 6
Source File: TypeCheck.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Emit a warning if we can prove that a property cannot possibly be
 * defined on an object. Note the difference between JS and a strictly
 * statically typed language: we're checking if the property
 * *cannot be defined*, whereas a java compiler would check if the
 * property *can be undefined*.
 */
private void checkPropertyAccess(JSType childType, String propName,
    NodeTraversal t, Node n) {
  // If the property type is unknown, check the object type to see if it
  // can ever be defined. We explicitly exclude CHECKED_UNKNOWN (for
  // properties where we've checked that it exists, or for properties on
  // objects that aren't in this binary).
  JSType propType = getJSType(n);
  if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
    childType = childType.autobox();
    ObjectType objectType = ObjectType.cast(childType);
    if (objectType != null) {
      // We special-case object types so that checks on enums can be
      // much stricter, and so that we can use hasProperty (which is much
      // faster in most cases).
      if (!objectType.hasProperty(propName) ||
          objectType.isEquivalentTo(
              typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        if (objectType instanceof EnumType) {
          report(t, n, INEXISTENT_ENUM_ELEMENT, propName);
        } else {
          checkPropertyAccessHelper(objectType, propName, t, n);
        }
      }

    } else {
      checkPropertyAccessHelper(childType, propName, t, n);
    }
  }
}
 
Example 7
Source File: Closure_125_TypeCheck_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Emit a warning if we can prove that a property cannot possibly be
 * defined on an object. Note the difference between JS and a strictly
 * statically typed language: we're checking if the property
 * *cannot be defined*, whereas a java compiler would check if the
 * property *can be undefined*.
 */
private void checkPropertyAccess(JSType childType, String propName,
    NodeTraversal t, Node n) {
  // If the property type is unknown, check the object type to see if it
  // can ever be defined. We explicitly exclude CHECKED_UNKNOWN (for
  // properties where we've checked that it exists, or for properties on
  // objects that aren't in this binary).
  JSType propType = getJSType(n);
  if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
    childType = childType.autobox();
    ObjectType objectType = ObjectType.cast(childType);
    if (objectType != null) {
      // We special-case object types so that checks on enums can be
      // much stricter, and so that we can use hasProperty (which is much
      // faster in most cases).
      if (!objectType.hasProperty(propName) ||
          objectType.isEquivalentTo(
              typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        if (objectType instanceof EnumType) {
          report(t, n, INEXISTENT_ENUM_ELEMENT, propName);
        } else {
          checkPropertyAccessHelper(objectType, propName, t, n);
        }
      }

    } else {
      checkPropertyAccessHelper(childType, propName, t, n);
    }
  }
}
 
Example 8
Source File: Nopol2017_0029_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Emit a warning if we can prove that a property cannot possibly be
 * defined on an object. Note the difference between JS and a strictly
 * statically typed language: we're checking if the property
 * *cannot be defined*, whereas a java compiler would check if the
 * property *can be undefined*.
 */
private void checkPropertyAccess(JSType childType, String propName,
    NodeTraversal t, Node n) {
  // If the property type is unknown, check the object type to see if it
  // can ever be defined. We explicitly exclude CHECKED_UNKNOWN (for
  // properties where we've checked that it exists, or for properties on
  // objects that aren't in this binary).
  JSType propType = getJSType(n);
  if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
    childType = childType.autobox();
    ObjectType objectType = ObjectType.cast(childType);
    if (objectType != null) {
      // We special-case object types so that checks on enums can be
      // much stricter, and so that we can use hasProperty (which is much
      // faster in most cases).
      if (!objectType.hasProperty(propName) ||
          objectType.isEquivalentTo(
              typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        if (objectType instanceof EnumType) {
          report(t, n, INEXISTENT_ENUM_ELEMENT, propName);
        } else {
          checkPropertyAccessHelper(objectType, propName, t, n);
        }
      }

    } else {
      checkPropertyAccessHelper(childType, propName, t, n);
    }
  }
}
 
Example 9
Source File: Closure_125_TypeCheck_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Emit a warning if we can prove that a property cannot possibly be
 * defined on an object. Note the difference between JS and a strictly
 * statically typed language: we're checking if the property
 * *cannot be defined*, whereas a java compiler would check if the
 * property *can be undefined*.
 */
private void checkPropertyAccess(JSType childType, String propName,
    NodeTraversal t, Node n) {
  // If the property type is unknown, check the object type to see if it
  // can ever be defined. We explicitly exclude CHECKED_UNKNOWN (for
  // properties where we've checked that it exists, or for properties on
  // objects that aren't in this binary).
  JSType propType = getJSType(n);
  if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
    childType = childType.autobox();
    ObjectType objectType = ObjectType.cast(childType);
    if (objectType != null) {
      // We special-case object types so that checks on enums can be
      // much stricter, and so that we can use hasProperty (which is much
      // faster in most cases).
      if (!objectType.hasProperty(propName) ||
          objectType.isEquivalentTo(
              typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        if (objectType instanceof EnumType) {
          report(t, n, INEXISTENT_ENUM_ELEMENT, propName);
        } else {
          checkPropertyAccessHelper(objectType, propName, t, n);
        }
      }

    } else {
      checkPropertyAccessHelper(childType, propName, t, n);
    }
  }
}
 
Example 10
Source File: Closure_2_TypeCheck_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Emit a warning if we can prove that a property cannot possibly be
 * defined on an object. Note the difference between JS and a strictly
 * statically typed language: we're checking if the property
 * *cannot be defined*, whereas a java compiler would check if the
 * property *can be undefined*.
 */
private void checkPropertyAccess(JSType childType, String propName,
    NodeTraversal t, Node n) {
  // If the property type is unknown, check the object type to see if it
  // can ever be defined. We explicitly exclude CHECKED_UNKNOWN (for
  // properties where we've checked that it exists, or for properties on
  // objects that aren't in this binary).
  JSType propType = getJSType(n);
  if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
    childType = childType.autobox();
    ObjectType objectType = ObjectType.cast(childType);
    if (objectType != null) {
      // We special-case object types so that checks on enums can be
      // much stricter, and so that we can use hasProperty (which is much
      // faster in most cases).
      if (!objectType.hasProperty(propName) ||
          objectType.isEquivalentTo(
              typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        if (objectType instanceof EnumType) {
          report(t, n, INEXISTENT_ENUM_ELEMENT, propName);
        } else {
          checkPropertyAccessHelper(objectType, propName, t, n);
        }
      }

    } else {
      checkPropertyAccessHelper(childType, propName, t, n);
    }
  }
}
 
Example 11
Source File: Closure_2_TypeCheck_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Emit a warning if we can prove that a property cannot possibly be
 * defined on an object. Note the difference between JS and a strictly
 * statically typed language: we're checking if the property
 * *cannot be defined*, whereas a java compiler would check if the
 * property *can be undefined*.
 */
private void checkPropertyAccess(JSType childType, String propName,
    NodeTraversal t, Node n) {
  // If the property type is unknown, check the object type to see if it
  // can ever be defined. We explicitly exclude CHECKED_UNKNOWN (for
  // properties where we've checked that it exists, or for properties on
  // objects that aren't in this binary).
  JSType propType = getJSType(n);
  if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
    childType = childType.autobox();
    ObjectType objectType = ObjectType.cast(childType);
    if (objectType != null) {
      // We special-case object types so that checks on enums can be
      // much stricter, and so that we can use hasProperty (which is much
      // faster in most cases).
      if (!objectType.hasProperty(propName) ||
          objectType.isEquivalentTo(
              typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        if (objectType instanceof EnumType) {
          report(t, n, INEXISTENT_ENUM_ELEMENT, propName);
        } else {
          checkPropertyAccessHelper(objectType, propName, t, n);
        }
      }

    } else {
      checkPropertyAccessHelper(childType, propName, t, n);
    }
  }
}
 
Example 12
Source File: Closure_112_TypeInference_s.java    From coming with MIT License 4 votes vote down vote up
private JSType getPropertyType(JSType objType, String propName,
    Node n, FlowScope scope) {
  // We often have a couple of different types to choose from for the
  // property. Ordered by accuracy, we have
  // 1) A locally inferred qualified name (which is in the FlowScope)
  // 2) A globally declared qualified name (which is in the FlowScope)
  // 3) A property on the owner type (which is on objType)
  // 4) A name in the type registry (as a last resort)
  JSType propertyType = null;
  boolean isLocallyInferred = false;

  // Scopes sometimes contain inferred type info about qualified names.
  String qualifiedName = n.getQualifiedName();
  StaticSlot<JSType> var = scope.getSlot(qualifiedName);
  if (var != null) {
    JSType varType = var.getType();
    if (varType != null) {
      boolean isDeclared = !var.isTypeInferred();
      isLocallyInferred = (var != syntacticScope.getSlot(qualifiedName));
      if (isDeclared || isLocallyInferred) {
        propertyType = varType;
      }
    }
  }

  if (propertyType == null && objType != null) {
    JSType foundType = objType.findPropertyType(propName);
    if (foundType != null) {
      propertyType = foundType;
    }
  }

  if (propertyType != null && objType != null) {
    JSType restrictedObjType = objType.restrictByNotNullOrUndefined();
    if (!restrictedObjType.getTemplateTypeMap().isEmpty()
        && propertyType.hasAnyTemplateTypes()) {
      TemplateTypeMap typeMap = restrictedObjType.getTemplateTypeMap();
      TemplateTypeMapReplacer replacer = new TemplateTypeMapReplacer(
          registry, typeMap);
      propertyType = propertyType.visit(replacer);
    }
  }

  if ((propertyType == null || propertyType.isUnknownType())
      && qualifiedName != null) {
    // If we find this node in the registry, then we can infer its type.
    ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
    if (regType != null) {
      propertyType = regType.getConstructor();
    }
  }

  if (propertyType == null) {
    return unknownType;
  } else if (propertyType.isEquivalentTo(unknownType) && isLocallyInferred) {
    // If the type has been checked in this scope,
    // then use CHECKED_UNKNOWN_TYPE instead to indicate that.
    return getNativeType(CHECKED_UNKNOWN_TYPE);
  } else {
    return propertyType;
  }
}
 
Example 13
Source File: CheckAccessControls.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Determines whether the given property is visible in the current context.
 * @param t The current traversal.
 * @param getprop The getprop node.
 */
private void checkPropertyVisibility(NodeTraversal t,
    Node getprop, Node parent) {
  ObjectType objectType =
      ObjectType.cast(dereference(getprop.getFirstChild().getJSType()));
  String propertyName = getprop.getLastChild().getString();

  if (objectType != null) {
    // Is this a normal property access, or are we trying to override
    // an existing property?
    boolean isOverride = parent.getJSDocInfo() != null &&
        parent.isAssign() &&
        parent.getFirstChild() == getprop;

    // Find the lowest property defined on a class with visibility
    // information.
    if (isOverride) {
      objectType = objectType.getImplicitPrototype();
    }
    JSDocInfo docInfo = null;
    for (; objectType != null;
         objectType = objectType.getImplicitPrototype()) {
      docInfo = objectType.getOwnPropertyJSDocInfo(propertyName);
      if (docInfo != null &&
          docInfo.getVisibility() != Visibility.INHERITED) {
        break;
      }
    }

    if (objectType == null) {
      // We couldn't find a visibility modifier; assume it's public.
      return;
    }

    String referenceSource = getprop.getSourceFileName();
    String definingSource = docInfo.getSourceName();
    boolean sameInput = referenceSource != null
        && referenceSource.equals(definingSource);
    Visibility visibility = docInfo.getVisibility();
    JSType ownerType = normalizeClassType(objectType);
    if (isOverride) {
      // Check an ASSIGN statement that's trying to override a property
      // on a superclass.
      JSDocInfo overridingInfo = parent.getJSDocInfo();
      Visibility overridingVisibility = overridingInfo == null ?
          Visibility.INHERITED : overridingInfo.getVisibility();

      // Check that (a) the property *can* be overridden, and
      // (b) that the visibility of the override is the same as the
      // visibility of the original property.
      if (visibility == Visibility.PRIVATE && !sameInput) {
        compiler.report(
            t.makeError(getprop, PRIVATE_OVERRIDE,
                objectType.toString()));
      } else if (overridingVisibility != Visibility.INHERITED &&
          overridingVisibility != visibility) {
        compiler.report(
            t.makeError(getprop, VISIBILITY_MISMATCH,
                visibility.name(), objectType.toString(),
                overridingVisibility.name()));
      }
    } else {
      if (sameInput) {
        // private access is always allowed in the same file.
        return;
      } else if (visibility == Visibility.PRIVATE &&
          (currentClass == null || !ownerType.isEquivalentTo(currentClass))) {
        if (docInfo.isConstructor() &&
            isValidPrivateConstructorAccess(parent)) {
          return;
        }

        // private access is not allowed outside the file from a different
        // enclosing class.
        compiler.report(
            t.makeError(getprop,
                BAD_PRIVATE_PROPERTY_ACCESS,
                propertyName,
                validator.getReadableJSTypeName(
                    getprop.getFirstChild(), true)));
      } else if (visibility == Visibility.PROTECTED) {
        // There are 3 types of legal accesses of a protected property:
        // 1) Accesses in the same file
        // 2) Overriding the property in a subclass
        // 3) Accessing the property from inside a subclass
        // The first two have already been checked for.
        if (currentClass == null || !currentClass.isSubtype(ownerType)) {
          compiler.report(
              t.makeError(getprop,  BAD_PROTECTED_PROPERTY_ACCESS,
                  propertyName,
                  validator.getReadableJSTypeName(
                      getprop.getFirstChild(), true)));
        }
      }
    }
  }
}
 
Example 14
Source File: TypeValidator.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Expect that the given variable has not been declared with a type.
 *
 * @param sourceName The name of the source file we're in.
 * @param n The node where warnings should point to.
 * @param parent The parent of {@code n}.
 * @param var The variable that we're checking.
 * @param variableName The name of the variable.
 * @param newType The type being applied to the variable. Mostly just here
 *     for the benefit of the warning.
 * @return The variable we end up with. Most of the time, this will just
 *     be {@code var}, but in some rare cases we will need to declare
 *     a new var with new source info.
 */
Var expectUndeclaredVariable(String sourceName, CompilerInput input,
    Node n, Node parent, Var var, String variableName, JSType newType) {
  Var newVar = var;
  boolean allowDupe = false;
  if (n.isGetProp() ||
      NodeUtil.isObjectLitKey(n, parent)) {
    JSDocInfo info = n.getJSDocInfo();
    if (info == null) {
      info = parent.getJSDocInfo();
    }
    allowDupe =
        info != null && info.getSuppressions().contains("duplicate");
  }

  JSType varType = var.getType();

  // Only report duplicate declarations that have types. Other duplicates
  // will be reported by the syntactic scope creator later in the
  // compilation process.
  if (varType != null &&
      varType != typeRegistry.getNativeType(UNKNOWN_TYPE) &&
      newType != null &&
      newType != typeRegistry.getNativeType(UNKNOWN_TYPE)) {
    // If there are two typed declarations of the same variable, that
    // is an error and the second declaration is ignored, except in the
    // case of native types. A null input type means that the declaration
    // was made in TypedScopeCreator#createInitialScope and is a
    // native type. We should redeclare it at the new input site.
    if (var.input == null) {
      Scope s = var.getScope();
      s.undeclare(var);
      newVar = s.declare(variableName, n, varType, input, false);

      n.setJSType(varType);
      if (parent.isVar()) {
        if (n.getFirstChild() != null) {
          n.getFirstChild().setJSType(varType);
        }
      } else {
        Preconditions.checkState(parent.isFunction());
        parent.setJSType(varType);
      }
    } else {
      // Always warn about duplicates if the overridden type does not
      // match the original type.
      //
      // If the types match, suppress the warning iff there was a @suppress
      // tag, or if the original declaration was a stub.
      if (!(allowDupe ||
            var.getParentNode().isExprResult()) ||
          !newType.isEquivalentTo(varType)) {
        report(JSError.make(sourceName, n, DUP_VAR_DECLARATION,
            variableName, newType.toString(), var.getInputName(),
            String.valueOf(var.nameNode.getLineno()),
            varType.toString()));
      }
    }
  }

  return newVar;
}
 
Example 15
Source File: Closure_6_TypeValidator_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Expect that the given variable has not been declared with a type.
 *
 * @param sourceName The name of the source file we're in.
 * @param n The node where warnings should point to.
 * @param parent The parent of {@code n}.
 * @param var The variable that we're checking.
 * @param variableName The name of the variable.
 * @param newType The type being applied to the variable. Mostly just here
 *     for the benefit of the warning.
 * @return The variable we end up with. Most of the time, this will just
 *     be {@code var}, but in some rare cases we will need to declare
 *     a new var with new source info.
 */
Var expectUndeclaredVariable(String sourceName, CompilerInput input,
    Node n, Node parent, Var var, String variableName, JSType newType) {
  Var newVar = var;
  boolean allowDupe = false;
  if (n.isGetProp() ||
      NodeUtil.isObjectLitKey(n, parent)) {
    JSDocInfo info = n.getJSDocInfo();
    if (info == null) {
      info = parent.getJSDocInfo();
    }
    allowDupe =
        info != null && info.getSuppressions().contains("duplicate");
  }

  JSType varType = var.getType();

  // Only report duplicate declarations that have types. Other duplicates
  // will be reported by the syntactic scope creator later in the
  // compilation process.
  if (varType != null &&
      varType != typeRegistry.getNativeType(UNKNOWN_TYPE) &&
      newType != null &&
      newType != typeRegistry.getNativeType(UNKNOWN_TYPE)) {
    // If there are two typed declarations of the same variable, that
    // is an error and the second declaration is ignored, except in the
    // case of native types. A null input type means that the declaration
    // was made in TypedScopeCreator#createInitialScope and is a
    // native type. We should redeclare it at the new input site.
    if (var.input == null) {
      Scope s = var.getScope();
      s.undeclare(var);
      newVar = s.declare(variableName, n, varType, input, false);

      n.setJSType(varType);
      if (parent.isVar()) {
        if (n.getFirstChild() != null) {
          n.getFirstChild().setJSType(varType);
        }
      } else {
        Preconditions.checkState(parent.isFunction());
        parent.setJSType(varType);
      }
    } else {
      // Always warn about duplicates if the overridden type does not
      // match the original type.
      //
      // If the types match, suppress the warning iff there was a @suppress
      // tag, or if the original declaration was a stub.
      if (!(allowDupe ||
            var.getParentNode().isExprResult()) ||
          !newType.isEquivalentTo(varType)) {
        report(JSError.make(sourceName, n, DUP_VAR_DECLARATION,
            variableName, newType.toString(), var.getInputName(),
            String.valueOf(var.nameNode.getLineno()),
            varType.toString()));
      }
    }
  }

  return newVar;
}
 
Example 16
Source File: Closure_6_TypeValidator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Expect that the given variable has not been declared with a type.
 *
 * @param sourceName The name of the source file we're in.
 * @param n The node where warnings should point to.
 * @param parent The parent of {@code n}.
 * @param var The variable that we're checking.
 * @param variableName The name of the variable.
 * @param newType The type being applied to the variable. Mostly just here
 *     for the benefit of the warning.
 * @return The variable we end up with. Most of the time, this will just
 *     be {@code var}, but in some rare cases we will need to declare
 *     a new var with new source info.
 */
Var expectUndeclaredVariable(String sourceName, CompilerInput input,
    Node n, Node parent, Var var, String variableName, JSType newType) {
  Var newVar = var;
  boolean allowDupe = false;
  if (n.isGetProp() ||
      NodeUtil.isObjectLitKey(n, parent)) {
    JSDocInfo info = n.getJSDocInfo();
    if (info == null) {
      info = parent.getJSDocInfo();
    }
    allowDupe =
        info != null && info.getSuppressions().contains("duplicate");
  }

  JSType varType = var.getType();

  // Only report duplicate declarations that have types. Other duplicates
  // will be reported by the syntactic scope creator later in the
  // compilation process.
  if (varType != null &&
      varType != typeRegistry.getNativeType(UNKNOWN_TYPE) &&
      newType != null &&
      newType != typeRegistry.getNativeType(UNKNOWN_TYPE)) {
    // If there are two typed declarations of the same variable, that
    // is an error and the second declaration is ignored, except in the
    // case of native types. A null input type means that the declaration
    // was made in TypedScopeCreator#createInitialScope and is a
    // native type. We should redeclare it at the new input site.
    if (var.input == null) {
      Scope s = var.getScope();
      s.undeclare(var);
      newVar = s.declare(variableName, n, varType, input, false);

      n.setJSType(varType);
      if (parent.isVar()) {
        if (n.getFirstChild() != null) {
          n.getFirstChild().setJSType(varType);
        }
      } else {
        Preconditions.checkState(parent.isFunction());
        parent.setJSType(varType);
      }
    } else {
      // Always warn about duplicates if the overridden type does not
      // match the original type.
      //
      // If the types match, suppress the warning iff there was a @suppress
      // tag, or if the original declaration was a stub.
      if (!(allowDupe ||
            var.getParentNode().isExprResult()) ||
          !newType.isEquivalentTo(varType)) {
        report(JSError.make(sourceName, n, DUP_VAR_DECLARATION,
            variableName, newType.toString(), var.getInputName(),
            String.valueOf(var.nameNode.getLineno()),
            varType.toString()));
      }
    }
  }

  return newVar;
}
 
Example 17
Source File: Closure_112_TypeInference_t.java    From coming with MIT License 4 votes vote down vote up
private JSType getPropertyType(JSType objType, String propName,
    Node n, FlowScope scope) {
  // We often have a couple of different types to choose from for the
  // property. Ordered by accuracy, we have
  // 1) A locally inferred qualified name (which is in the FlowScope)
  // 2) A globally declared qualified name (which is in the FlowScope)
  // 3) A property on the owner type (which is on objType)
  // 4) A name in the type registry (as a last resort)
  JSType propertyType = null;
  boolean isLocallyInferred = false;

  // Scopes sometimes contain inferred type info about qualified names.
  String qualifiedName = n.getQualifiedName();
  StaticSlot<JSType> var = scope.getSlot(qualifiedName);
  if (var != null) {
    JSType varType = var.getType();
    if (varType != null) {
      boolean isDeclared = !var.isTypeInferred();
      isLocallyInferred = (var != syntacticScope.getSlot(qualifiedName));
      if (isDeclared || isLocallyInferred) {
        propertyType = varType;
      }
    }
  }

  if (propertyType == null && objType != null) {
    JSType foundType = objType.findPropertyType(propName);
    if (foundType != null) {
      propertyType = foundType;
    }
  }

  if (propertyType != null && objType != null) {
    JSType restrictedObjType = objType.restrictByNotNullOrUndefined();
    if (!restrictedObjType.getTemplateTypeMap().isEmpty()
        && propertyType.hasAnyTemplateTypes()) {
      TemplateTypeMap typeMap = restrictedObjType.getTemplateTypeMap();
      TemplateTypeMapReplacer replacer = new TemplateTypeMapReplacer(
          registry, typeMap);
      propertyType = propertyType.visit(replacer);
    }
  }

  if ((propertyType == null || propertyType.isUnknownType())
      && qualifiedName != null) {
    // If we find this node in the registry, then we can infer its type.
    ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
    if (regType != null) {
      propertyType = regType.getConstructor();
    }
  }

  if (propertyType == null) {
    return unknownType;
  } else if (propertyType.isEquivalentTo(unknownType) && isLocallyInferred) {
    // If the type has been checked in this scope,
    // then use CHECKED_UNKNOWN_TYPE instead to indicate that.
    return getNativeType(CHECKED_UNKNOWN_TYPE);
  } else {
    return propertyType;
  }
}
 
Example 18
Source File: Closure_117_TypeValidator_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Expect that the given variable has not been declared with a type.
 *
 * @param sourceName The name of the source file we're in.
 * @param n The node where warnings should point to.
 * @param parent The parent of {@code n}.
 * @param var The variable that we're checking.
 * @param variableName The name of the variable.
 * @param newType The type being applied to the variable. Mostly just here
 *     for the benefit of the warning.
 * @return The variable we end up with. Most of the time, this will just
 *     be {@code var}, but in some rare cases we will need to declare
 *     a new var with new source info.
 */
Var expectUndeclaredVariable(String sourceName, CompilerInput input,
    Node n, Node parent, Var var, String variableName, JSType newType) {
  Var newVar = var;
  boolean allowDupe = false;
  if (n.isGetProp() ||
      NodeUtil.isObjectLitKey(n)) {
    JSDocInfo info = n.getJSDocInfo();
    if (info == null) {
      info = parent.getJSDocInfo();
    }
    allowDupe =
        info != null && info.getSuppressions().contains("duplicate");
  }

  JSType varType = var.getType();

  // Only report duplicate declarations that have types. Other duplicates
  // will be reported by the syntactic scope creator later in the
  // compilation process.
  if (varType != null &&
      varType != typeRegistry.getNativeType(UNKNOWN_TYPE) &&
      newType != null &&
      newType != typeRegistry.getNativeType(UNKNOWN_TYPE)) {
    // If there are two typed declarations of the same variable, that
    // is an error and the second declaration is ignored, except in the
    // case of native types. A null input type means that the declaration
    // was made in TypedScopeCreator#createInitialScope and is a
    // native type. We should redeclare it at the new input site.
    if (var.input == null) {
      Scope s = var.getScope();
      s.undeclare(var);
      newVar = s.declare(variableName, n, varType, input, false);

      n.setJSType(varType);
      if (parent.isVar()) {
        if (n.getFirstChild() != null) {
          n.getFirstChild().setJSType(varType);
        }
      } else {
        Preconditions.checkState(parent.isFunction());
        parent.setJSType(varType);
      }
    } else {
      // Always warn about duplicates if the overridden type does not
      // match the original type.
      //
      // If the types match, suppress the warning iff there was a @suppress
      // tag, or if the original declaration was a stub.
      if (!(allowDupe ||
            var.getParentNode().isExprResult()) ||
          !newType.isEquivalentTo(varType)) {
        report(JSError.make(sourceName, n, DUP_VAR_DECLARATION,
            variableName, newType.toString(), var.getInputName(),
            String.valueOf(var.nameNode.getLineno()),
            varType.toString()));
      }
    }
  }

  return newVar;
}
 
Example 19
Source File: Closure_117_TypeValidator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Expect that the given variable has not been declared with a type.
 *
 * @param sourceName The name of the source file we're in.
 * @param n The node where warnings should point to.
 * @param parent The parent of {@code n}.
 * @param var The variable that we're checking.
 * @param variableName The name of the variable.
 * @param newType The type being applied to the variable. Mostly just here
 *     for the benefit of the warning.
 * @return The variable we end up with. Most of the time, this will just
 *     be {@code var}, but in some rare cases we will need to declare
 *     a new var with new source info.
 */
Var expectUndeclaredVariable(String sourceName, CompilerInput input,
    Node n, Node parent, Var var, String variableName, JSType newType) {
  Var newVar = var;
  boolean allowDupe = false;
  if (n.isGetProp() ||
      NodeUtil.isObjectLitKey(n)) {
    JSDocInfo info = n.getJSDocInfo();
    if (info == null) {
      info = parent.getJSDocInfo();
    }
    allowDupe =
        info != null && info.getSuppressions().contains("duplicate");
  }

  JSType varType = var.getType();

  // Only report duplicate declarations that have types. Other duplicates
  // will be reported by the syntactic scope creator later in the
  // compilation process.
  if (varType != null &&
      varType != typeRegistry.getNativeType(UNKNOWN_TYPE) &&
      newType != null &&
      newType != typeRegistry.getNativeType(UNKNOWN_TYPE)) {
    // If there are two typed declarations of the same variable, that
    // is an error and the second declaration is ignored, except in the
    // case of native types. A null input type means that the declaration
    // was made in TypedScopeCreator#createInitialScope and is a
    // native type. We should redeclare it at the new input site.
    if (var.input == null) {
      Scope s = var.getScope();
      s.undeclare(var);
      newVar = s.declare(variableName, n, varType, input, false);

      n.setJSType(varType);
      if (parent.isVar()) {
        if (n.getFirstChild() != null) {
          n.getFirstChild().setJSType(varType);
        }
      } else {
        Preconditions.checkState(parent.isFunction());
        parent.setJSType(varType);
      }
    } else {
      // Always warn about duplicates if the overridden type does not
      // match the original type.
      //
      // If the types match, suppress the warning iff there was a @suppress
      // tag, or if the original declaration was a stub.
      if (!(allowDupe ||
            var.getParentNode().isExprResult()) ||
          !newType.isEquivalentTo(varType)) {
        report(JSError.make(sourceName, n, DUP_VAR_DECLARATION,
            variableName, newType.toString(), var.getInputName(),
            String.valueOf(var.nameNode.getLineno()),
            varType.toString()));
      }
    }
  }

  return newVar;
}
 
Example 20
Source File: TypeInference.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
private JSType getPropertyType(JSType objType, String propName,
    Node n, FlowScope scope) {
  // We often have a couple of different types to choose from for the
  // property. Ordered by accuracy, we have
  // 1) A locally inferred qualified name (which is in the FlowScope)
  // 2) A globally declared qualified name (which is in the FlowScope)
  // 3) A property on the owner type (which is on objType)
  // 4) A name in the type registry (as a last resort)
  JSType propertyType = null;
  boolean isLocallyInferred = false;

  // Scopes sometimes contain inferred type info about qualified names.
  String qualifiedName = n.getQualifiedName();
  StaticSlot<JSType> var = scope.getSlot(qualifiedName);
  if (var != null) {
    JSType varType = var.getType();
    if (varType != null) {
      boolean isDeclared = !var.isTypeInferred();
      isLocallyInferred = (var != syntacticScope.getSlot(qualifiedName));
      if (isDeclared || isLocallyInferred) {
        propertyType = varType;
      }
    }
  }

  if (propertyType == null && objType != null) {
    JSType foundType = objType.findPropertyType(propName);
    if (foundType != null) {
      propertyType = foundType;
    }
  }

  if ((propertyType == null || propertyType.isUnknownType())
      && qualifiedName != null) {
    // If we find this node in the registry, then we can infer its type.
    ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
    if (regType != null) {
      propertyType = regType.getConstructor();
    }
  }

  if (propertyType == null) {
    return unknownType;
  } else if (propertyType.isEquivalentTo(unknownType) && isLocallyInferred) {
    // If the type has been checked in this scope,
    // then use CHECKED_UNKNOWN_TYPE instead to indicate that.
    return getNativeType(CHECKED_UNKNOWN_TYPE);
  } else {
    return propertyType;
  }
}