Java Code Examples for com.google.javascript.rhino.jstype.FunctionType#getSuperClassConstructor()

The following examples show how to use com.google.javascript.rhino.jstype.FunctionType#getSuperClassConstructor() . 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: TypeRegistry.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
private JSType getSuperInstance(
    ObjectType instance,
    FunctionType ctor,
    StaticTypedScope globalScope,
    JSTypeRegistry jsRegistry) {
  JSType superInstance;
  if (ctor.getJSDocInfo() != null && ctor.getJSDocInfo().getBaseType() != null) {
    List<TemplateType> templateTypes = instance.getTemplateTypeMap().getTemplateKeys();
    StaticTypedScope scope =
        templateTypes.isEmpty()
            ? globalScope
            : jsRegistry.createScopeWithTemplates(globalScope, templateTypes);

    JSTypeExpression baseTypeExpression = ctor.getJSDocInfo().getBaseType();
    superInstance = Types.evaluate(baseTypeExpression, scope, jsRegistry);

    // The type expression will resolve to a named type if it is an aliased reference to
    // a module's exported type. Compensate by checking dossier's type registry, which
    // tracks exported types by their exported name (whereas the compiler tracks them by
    // their initially declared name from within the module).
    if (superInstance.isNamedType()
        && isType(superInstance.toMaybeNamedType().getReferenceName())) {
      superInstance = getType(superInstance.toMaybeNamedType().getReferenceName()).getType();
      if (superInstance.isConstructor() || superInstance.isInterface()) {
        superInstance = superInstance.toMaybeFunctionType().getTypeOfThis();
      }
    }

  } else {
    FunctionType superCtor = ctor.getSuperClassConstructor();
    if (superCtor == null) {
      return null;
    }
    superInstance = superCtor.getTypeOfThis();
  }
  return superInstance;
}
 
Example 2
Source File: TypeRegistry.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
private void computeTypeHiearchy(
    final FunctionType ctor, StaticTypedScope globalScope, JSTypeRegistry jsRegistry) {
  checkArgument(ctor.isConstructor());

  List<JSType> types = new ArrayList<>();
  FunctionType currentCtor = ctor;
  JSType currentInstance = getInstanceType(jsRegistry, ctor);
  while (currentInstance != null
      && currentCtor != null
      && currentCtor.getSuperClassConstructor() != null) {
    types.add(currentInstance);

    JSType superInstance =
        getSuperInstance(
            currentInstance.toMaybeObjectType(), currentCtor, globalScope, jsRegistry);
    if (superInstance == null || superInstance.toMaybeObjectType() == null) {
      break;
    }

    FunctionType superCtor = superInstance.toMaybeObjectType().getConstructor();
    if (superCtor != null) {
      directSubtypes.put(superCtor, getInstanceType(jsRegistry, currentCtor));
    }
    currentInstance = superInstance;
    currentCtor = superCtor;
  }
  typeHierarchy.putAll(ctor, types);
}
 
Example 3
Source File: DisambiguateProperties.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void recordInterfaces(JSType type, JSType relatedType,
                             DisambiguateProperties<JSType>.Property p) {
  ObjectType objType = ObjectType.cast(type);
  if (objType != null) {
    FunctionType constructor;
    if (objType.isFunctionType()) {
      constructor = objType.toMaybeFunctionType();
    } else if (objType.isFunctionPrototypeType()) {
      constructor = objType.getOwnerFunction();
    } else {
      constructor = objType.getConstructor();
    }
    while (constructor != null) {
      for (ObjectType itype : constructor.getImplementedInterfaces()) {
        JSType top = getTypeWithProperty(p.name, itype);
        if (top != null) {
          p.addType(itype, top, relatedType);
        } else {
          recordInterfaces(itype, relatedType, p);
        }

        // If this interface invalidated this property, return now.
        if (p.skipRenaming) return;
      }
      if (constructor.isInterface() || constructor.isConstructor()) {
        constructor = constructor.getSuperClassConstructor();
      } else {
        constructor = null;
      }
    }
  }
}
 
Example 4
Source File: Closure_118_DisambiguateProperties_t.java    From coming with MIT License 5 votes vote down vote up
@Override
public void recordInterfaces(JSType type, JSType relatedType,
                             DisambiguateProperties<JSType>.Property p) {
  ObjectType objType = ObjectType.cast(type);
  if (objType != null) {
    FunctionType constructor;
    if (objType.isFunctionType()) {
      constructor = objType.toMaybeFunctionType();
    } else if (objType.isFunctionPrototypeType()) {
      constructor = objType.getOwnerFunction();
    } else {
      constructor = objType.getConstructor();
    }
    while (constructor != null) {
      for (ObjectType itype : constructor.getImplementedInterfaces()) {
        JSType top = getTypeWithProperty(p.name, itype);
        if (top != null) {
          p.addType(itype, top, relatedType);
        } else {
          recordInterfaces(itype, relatedType, p);
        }

        // If this interface invalidated this property, return now.
        if (p.skipRenaming) {
          return;
        }
      }
      if (constructor.isInterface() || constructor.isConstructor()) {
        constructor = constructor.getSuperClassConstructor();
      } else {
        constructor = null;
      }
    }
  }
}
 
Example 5
Source File: Closure_118_DisambiguateProperties_s.java    From coming with MIT License 5 votes vote down vote up
@Override
public void recordInterfaces(JSType type, JSType relatedType,
                             DisambiguateProperties<JSType>.Property p) {
  ObjectType objType = ObjectType.cast(type);
  if (objType != null) {
    FunctionType constructor;
    if (objType.isFunctionType()) {
      constructor = objType.toMaybeFunctionType();
    } else if (objType.isFunctionPrototypeType()) {
      constructor = objType.getOwnerFunction();
    } else {
      constructor = objType.getConstructor();
    }
    while (constructor != null) {
      for (ObjectType itype : constructor.getImplementedInterfaces()) {
        JSType top = getTypeWithProperty(p.name, itype);
        if (top != null) {
          p.addType(itype, top, relatedType);
        } else {
          recordInterfaces(itype, relatedType, p);
        }

        // If this interface invalidated this property, return now.
        if (p.skipRenaming) {
          return;
        }
      }
      if (constructor.isInterface() || constructor.isConstructor()) {
        constructor = constructor.getSuperClassConstructor();
      } else {
        constructor = null;
      }
    }
  }
}
 
Example 6
Source File: NameReferenceGraphConstruction.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Look for the super class implementation up the tree.
 */
private void recordSuperClassPrototypePropUse(
    FunctionType classType, String prop, Reference ref) {
  FunctionType superClass = classType.getSuperClassConstructor();
  while (superClass != null) {
    if (superClass.getPrototype().hasOwnProperty(prop)) {
      graph.connect(getNamedContainingFunction(), ref,
          graph.defineNameIfNotExists(
             superClass.getReferenceName() + ".prototype." + prop, false));
      return;
    } else {
      superClass = superClass.getSuperClassConstructor();
    }
  }
}
 
Example 7
Source File: Closure_96_TypeCheck_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Given a constructor type and a property name, check that the property has
 * the JSDoc annotation @override iff the property is declared on a
 * superclass. Several checks regarding inheritance correctness are also
 * performed.
 */
private void checkDeclaredPropertyInheritance(
    NodeTraversal t, Node n, FunctionType ctorType, String propertyName,
    JSDocInfo info, JSType propertyType) {
  // TODO(user): We're not 100% confident that type-checking works,
  // so we return quietly if the unknown type is a superclass of this type.
  // Remove this check as we become more confident. We should flag a warning
  // when the unknown type is on the inheritance chain, as it is likely
  // because of a programmer error.
  if (ctorType.hasUnknownSupertype()) {
    return;
  }

  FunctionType superClass = ctorType.getSuperClassConstructor();
  boolean superClassHasProperty = superClass != null &&
      superClass.getPrototype().hasProperty(propertyName);
  boolean declaredOverride = info != null && info.isOverride();

  boolean foundInterfaceProperty = false;
  if (ctorType.isConstructor()) {
    for (JSType implementedInterface : ctorType.getImplementedInterfaces()) {
      if (implementedInterface.isUnknownType()) {
        continue;
      }
      FunctionType interfaceType =
          implementedInterface.toObjectType().getConstructor();
      boolean interfaceHasProperty =
          interfaceType.getPrototype().hasProperty(propertyName);
      foundInterfaceProperty = foundInterfaceProperty || interfaceHasProperty;
      if (reportMissingOverride.isOn() && !declaredOverride &&
          interfaceHasProperty) {
        // @override not present, but the property does override an interface
        // property
        compiler.report(t.makeError(n, reportMissingOverride,
            HIDDEN_INTERFACE_PROPERTY, propertyName,
            interfaceType.getTopMostDefiningType(propertyName).toString()));
      }
      if (!declaredOverride) {
        continue;
      }
      // @override is present and we have to check that it is ok
      if (interfaceHasProperty) {
        JSType interfacePropType =
            interfaceType.getPrototype().getPropertyType(propertyName);
        if (!propertyType.canAssignTo(interfacePropType)) {
          compiler.report(t.makeError(n,
              HIDDEN_INTERFACE_PROPERTY_MISMATCH, propertyName,
              interfaceType.getTopMostDefiningType(propertyName).toString(),
              interfacePropType.toString(), propertyType.toString()));
        }
      }
    }
  }

  if (!declaredOverride && !superClassHasProperty) {
    // nothing to do here, it's just a plain new property
    return;
  }

  JSType topInstanceType = superClassHasProperty ?
      superClass.getTopMostDefiningType(propertyName) : null;
  if (reportMissingOverride.isOn() && ctorType.isConstructor() &&
      !declaredOverride && superClassHasProperty) {
    // @override not present, but the property does override a superclass
    // property
    compiler.report(t.makeError(n, reportMissingOverride,
        HIDDEN_SUPERCLASS_PROPERTY, propertyName,
        topInstanceType.toString()));
  }
  if (!declaredOverride) {
    // there's no @override to check
    return;
  }
  // @override is present and we have to check that it is ok
  if (superClassHasProperty) {
    // there is a superclass implementation
    JSType superClassPropType =
        superClass.getPrototype().getPropertyType(propertyName);
    if (!propertyType.canAssignTo(superClassPropType)) {
      compiler.report(
          t.makeError(n, HIDDEN_SUPERCLASS_PROPERTY_MISMATCH,
              propertyName, topInstanceType.toString(),
              superClassPropType.toString(), propertyType.toString()));
    }
  } else if (!foundInterfaceProperty) {
    // there is no superclass nor interface implementation
    compiler.report(
        t.makeError(n, UNKNOWN_OVERRIDE,
            propertyName, ctorType.getInstanceType().toString()));
  }
}
 
Example 8
Source File: TypedScopeCreator.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
private void finishConstructorDefinition(
    Node n, String variableName, FunctionType fnType,
    Scope scopeToDeclareIn, CompilerInput input, Var newVar) {
  // Declare var.prototype in the scope chain.
  FunctionType superClassCtor = fnType.getSuperClassConstructor();
  Property prototypeSlot = fnType.getSlot("prototype");

  // When we declare the function prototype implicitly, we
  // want to make sure that the function and its prototype
  // are declared at the same node. We also want to make sure
  // that the if a symbol has both a Var and a JSType, they have
  // the same node.
  //
  // This consistency is helpful to users of SymbolTable,
  // because everything gets declared at the same place.
  prototypeSlot.setNode(n);

  String prototypeName = variableName + ".prototype";

  // There are some rare cases where the prototype will already
  // be declared. See TypedScopeCreatorTest#testBogusPrototypeInit.
  // Fortunately, other warnings will complain if this happens.
  Var prototypeVar = scopeToDeclareIn.getVar(prototypeName);
  if (prototypeVar != null && prototypeVar.scope == scopeToDeclareIn) {
    scopeToDeclareIn.undeclare(prototypeVar);
  }

  scopeToDeclareIn.declare(prototypeName,
      n, prototypeSlot.getType(), input,
      /* declared iff there's an explicit supertype */
      superClassCtor == null ||
      superClassCtor.getInstanceType().isEquivalentTo(
          getNativeType(OBJECT_TYPE)));

  // Make sure the variable is initialized to something if
  // it constructs itself.
  if (newVar.getInitialValue() == null &&
      !n.isFromExterns()) {
    compiler.report(
        JSError.make(sourceName, n,
            fnType.isConstructor() ?
            CTOR_INITIALIZER : IFACE_INITIALIZER,
            variableName));
  }
}
 
Example 9
Source File: TypeCheck.java    From astor with GNU General Public License v2.0 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE)) {
        ObjectType proto = functionType.getPrototype();
        if (functionType.makesStructs() && !proto.isStruct()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() && !proto.isDict()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }

    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        checkInterfaceConflictProperties(t, n, functionPrivateName,
            properties, currentProperties, interfaceType);
        properties.putAll(currentProperties);
      }
    }
  }
}
 
Example 10
Source File: Closure_2_TypeCheck_t.java    From coming with MIT License 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE)) {
        ObjectType proto = functionType.getPrototype();
        if (functionType.makesStructs() && !proto.isStruct()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() && !proto.isDict()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }

    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        checkInterfaceConflictProperties(t, n, functionPrivateName,
            properties, currentProperties, interfaceType);
        properties.putAll(currentProperties);
      }
    }
  }
}
 
Example 11
Source File: Closure_2_TypeCheck_s.java    From coming with MIT License 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE)) {
        ObjectType proto = functionType.getPrototype();
        if (functionType.makesStructs() && !proto.isStruct()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() && !proto.isDict()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }

    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        checkInterfaceConflictProperties(t, n, functionPrivateName,
            properties, currentProperties, interfaceType);
        properties.putAll(currentProperties);
      }
    }
  }
}
 
Example 12
Source File: Closure_96_TypeCheck_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Given a constructor type and a property name, check that the property has
 * the JSDoc annotation @override iff the property is declared on a
 * superclass. Several checks regarding inheritance correctness are also
 * performed.
 */
private void checkDeclaredPropertyInheritance(
    NodeTraversal t, Node n, FunctionType ctorType, String propertyName,
    JSDocInfo info, JSType propertyType) {
  // TODO(user): We're not 100% confident that type-checking works,
  // so we return quietly if the unknown type is a superclass of this type.
  // Remove this check as we become more confident. We should flag a warning
  // when the unknown type is on the inheritance chain, as it is likely
  // because of a programmer error.
  if (ctorType.hasUnknownSupertype()) {
    return;
  }

  FunctionType superClass = ctorType.getSuperClassConstructor();
  boolean superClassHasProperty = superClass != null &&
      superClass.getPrototype().hasProperty(propertyName);
  boolean declaredOverride = info != null && info.isOverride();

  boolean foundInterfaceProperty = false;
  if (ctorType.isConstructor()) {
    for (JSType implementedInterface : ctorType.getImplementedInterfaces()) {
      if (implementedInterface.isUnknownType()) {
        continue;
      }
      FunctionType interfaceType =
          implementedInterface.toObjectType().getConstructor();
      boolean interfaceHasProperty =
          interfaceType.getPrototype().hasProperty(propertyName);
      foundInterfaceProperty = foundInterfaceProperty || interfaceHasProperty;
      if (reportMissingOverride.isOn() && !declaredOverride &&
          interfaceHasProperty) {
        // @override not present, but the property does override an interface
        // property
        compiler.report(t.makeError(n, reportMissingOverride,
            HIDDEN_INTERFACE_PROPERTY, propertyName,
            interfaceType.getTopMostDefiningType(propertyName).toString()));
      }
      if (!declaredOverride) {
        continue;
      }
      // @override is present and we have to check that it is ok
      if (interfaceHasProperty) {
        JSType interfacePropType =
            interfaceType.getPrototype().getPropertyType(propertyName);
        if (!propertyType.canAssignTo(interfacePropType)) {
          compiler.report(t.makeError(n,
              HIDDEN_INTERFACE_PROPERTY_MISMATCH, propertyName,
              interfaceType.getTopMostDefiningType(propertyName).toString(),
              interfacePropType.toString(), propertyType.toString()));
        }
      }
    }
  }

  if (!declaredOverride && !superClassHasProperty) {
    // nothing to do here, it's just a plain new property
    return;
  }

  JSType topInstanceType = superClassHasProperty ?
      superClass.getTopMostDefiningType(propertyName) : null;
  if (reportMissingOverride.isOn() && ctorType.isConstructor() &&
      !declaredOverride && superClassHasProperty) {
    // @override not present, but the property does override a superclass
    // property
    compiler.report(t.makeError(n, reportMissingOverride,
        HIDDEN_SUPERCLASS_PROPERTY, propertyName,
        topInstanceType.toString()));
  }
  if (!declaredOverride) {
    // there's no @override to check
    return;
  }
  // @override is present and we have to check that it is ok
  if (superClassHasProperty) {
    // there is a superclass implementation
    JSType superClassPropType =
        superClass.getPrototype().getPropertyType(propertyName);
    if (!propertyType.canAssignTo(superClassPropType)) {
      compiler.report(
          t.makeError(n, HIDDEN_SUPERCLASS_PROPERTY_MISMATCH,
              propertyName, topInstanceType.toString(),
              superClassPropType.toString(), propertyType.toString()));
    }
  } else if (!foundInterfaceProperty) {
    // there is no superclass nor interface implementation
    compiler.report(
        t.makeError(n, UNKNOWN_OVERRIDE,
            propertyName, ctorType.getInstanceType().toString()));
  }
}
 
Example 13
Source File: Nopol2017_0029_t.java    From coming with MIT License 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE)) {
        ObjectType proto = functionType.getPrototype();
        if (functionType.makesStructs() && !proto.isStruct()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() && !proto.isDict()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }

    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        if (com.google.javascript.jscomp.TypeCheck.this.unknownCount < com.google.javascript.jscomp.TypeCheck.this.typedCount) {
          checkInterfaceConflictProperties(t, n, functionPrivateName,
          properties, currentProperties, interfaceType);
        }
        properties.putAll(currentProperties);
      }
    }
  }
}
 
Example 14
Source File: Closure_95_TypedScopeCreator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Defines a typed variable. The defining node will be annotated with the
 * variable's type of {@link JSTypeNative#UNKNOWN_TYPE} if its type is
 * inferred.
 *
 * Slots may be any variable or any qualified name in the global scope.
 *
 * @param n the defining NAME or GETPROP node.
 * @param parent the {@code n}'s parent.
 * @param type the variable's type. It may be {@code null} if
 *     {@code inferred} is {@code true}.
 */
void defineSlot(Node n, Node parent, JSType type, boolean inferred) {
  Preconditions.checkArgument(inferred || type != null);

  // Only allow declarations of NAMEs and qualfied names.
  boolean shouldDeclareOnGlobalThis = false;
  if (n.getType() == Token.NAME) {
    Preconditions.checkArgument(
        parent.getType() == Token.FUNCTION ||
        parent.getType() == Token.VAR ||
        parent.getType() == Token.LP ||
        parent.getType() == Token.CATCH);
    shouldDeclareOnGlobalThis = scope.isGlobal() &&
        (parent.getType() == Token.VAR ||
         parent.getType() == Token.FUNCTION);
  } else {
    Preconditions.checkArgument(
        n.getType() == Token.GETPROP &&
        (parent.getType() == Token.ASSIGN ||
         parent.getType() == Token.EXPR_RESULT));
  }
  String variableName = n.getQualifiedName();
  Preconditions.checkArgument(!variableName.isEmpty());

  // If n is a property, then we should really declare it in the
  // scope where the root object appears. This helps out people
  // who declare "global" names in an anonymous namespace.
  Scope scopeToDeclareIn = scope;
  if (n.getType() == Token.GETPROP && !scope.isGlobal() &&
      isQnameRootedInGlobalScope(n)) {
    Scope globalScope = scope.getGlobalScope();

    // don't try to declare in the global scope if there's
    // already a symbol there with this name.
    if (!globalScope.isDeclared(variableName, false)) {
      scopeToDeclareIn = scope.getGlobalScope();
    }
  }

  // declared in closest scope?
  if (scopeToDeclareIn.isDeclared(variableName, false)) {
    Var oldVar = scopeToDeclareIn.getVar(variableName);
    validator.expectUndeclaredVariable(
        sourceName, n, parent, oldVar, variableName, type);
  } else {
    if (!inferred) {
      setDeferredType(n, type);
    }
    CompilerInput input = compiler.getInput(sourceName);
    scopeToDeclareIn.declare(variableName, n, type, input, inferred);

    if (shouldDeclareOnGlobalThis) {
      ObjectType globalThis =
          typeRegistry.getNativeObjectType(JSTypeNative.GLOBAL_THIS);
      boolean isExtern = input.isExtern();
      if (inferred) {
        globalThis.defineInferredProperty(variableName,
            type == null ?
                getNativeType(JSTypeNative.NO_TYPE) :
                type,
            isExtern);
      } else {
        globalThis.defineDeclaredProperty(variableName, type, isExtern);
      }
    }

    // If we're in the global scope, also declare var.prototype
    // in the scope chain.
    if (scopeToDeclareIn.isGlobal() && type instanceof FunctionType) {
      FunctionType fnType = (FunctionType) type;
      if (fnType.isConstructor() || fnType.isInterface()) {
        FunctionType superClassCtor = fnType.getSuperClassConstructor();
        scopeToDeclareIn.declare(variableName + ".prototype", n,
            fnType.getPrototype(), compiler.getInput(sourceName),
            /* declared iff there's an explicit supertype */
            superClassCtor == null ||
            superClassCtor.getInstanceType().equals(
                getNativeType(OBJECT_TYPE)));
      }
    }
  }
}
 
Example 15
Source File: Closure_95_TypedScopeCreator_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Defines a typed variable. The defining node will be annotated with the
 * variable's type of {@link JSTypeNative#UNKNOWN_TYPE} if its type is
 * inferred.
 *
 * Slots may be any variable or any qualified name in the global scope.
 *
 * @param n the defining NAME or GETPROP node.
 * @param parent the {@code n}'s parent.
 * @param type the variable's type. It may be {@code null} if
 *     {@code inferred} is {@code true}.
 */
void defineSlot(Node n, Node parent, JSType type, boolean inferred) {
  Preconditions.checkArgument(inferred || type != null);

  // Only allow declarations of NAMEs and qualfied names.
  boolean shouldDeclareOnGlobalThis = false;
  if (n.getType() == Token.NAME) {
    Preconditions.checkArgument(
        parent.getType() == Token.FUNCTION ||
        parent.getType() == Token.VAR ||
        parent.getType() == Token.LP ||
        parent.getType() == Token.CATCH);
    shouldDeclareOnGlobalThis = scope.isGlobal() &&
        (parent.getType() == Token.VAR ||
         parent.getType() == Token.FUNCTION);
  } else {
    Preconditions.checkArgument(
        n.getType() == Token.GETPROP &&
        (parent.getType() == Token.ASSIGN ||
         parent.getType() == Token.EXPR_RESULT));
  }
  String variableName = n.getQualifiedName();
  Preconditions.checkArgument(!variableName.isEmpty());

  // If n is a property, then we should really declare it in the
  // scope where the root object appears. This helps out people
  // who declare "global" names in an anonymous namespace.
  Scope scopeToDeclareIn = scope;

    // don't try to declare in the global scope if there's
    // already a symbol there with this name.

  // declared in closest scope?
  if (scopeToDeclareIn.isDeclared(variableName, false)) {
    Var oldVar = scopeToDeclareIn.getVar(variableName);
    validator.expectUndeclaredVariable(
        sourceName, n, parent, oldVar, variableName, type);
  } else {
    if (!inferred) {
      setDeferredType(n, type);
    }
    CompilerInput input = compiler.getInput(sourceName);
    scopeToDeclareIn.declare(variableName, n, type, input, inferred);

    if (shouldDeclareOnGlobalThis) {
      ObjectType globalThis =
          typeRegistry.getNativeObjectType(JSTypeNative.GLOBAL_THIS);
      boolean isExtern = input.isExtern();
      if (inferred) {
        globalThis.defineInferredProperty(variableName,
            type == null ?
                getNativeType(JSTypeNative.NO_TYPE) :
                type,
            isExtern);
      } else {
        globalThis.defineDeclaredProperty(variableName, type, isExtern);
      }
    }

    // If we're in the global scope, also declare var.prototype
    // in the scope chain.
    if (scopeToDeclareIn.isGlobal() && type instanceof FunctionType) {
      FunctionType fnType = (FunctionType) type;
      if (fnType.isConstructor() || fnType.isInterface()) {
        FunctionType superClassCtor = fnType.getSuperClassConstructor();
        scopeToDeclareIn.declare(variableName + ".prototype", n,
            fnType.getPrototype(), compiler.getInput(sourceName),
            /* declared iff there's an explicit supertype */
            superClassCtor == null ||
            superClassCtor.getInstanceType().equals(
                getNativeType(OBJECT_TYPE)));
      }
    }
  }
}
 
Example 16
Source File: Closure_11_TypeCheck_t.java    From coming with MIT License 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface() && functionType.isConstructor()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
          baseConstructor != null) {
        if (functionType.makesStructs() && !baseConstructor.makesStructs()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() &&
                   !baseConstructor.makesDicts()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }
    // Interface cannot implement any interfaces
    if (functionType.hasImplementedInterfaces()) {
      compiler.report(t.makeError(n,
          CONFLICTING_IMPLEMENTED_TYPE, functionPrivateName));
    }
    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        checkInterfaceConflictProperties(t, n, functionPrivateName,
            properties, currentProperties, interfaceType);
        properties.putAll(currentProperties);
      }
    }
  }
}
 
Example 17
Source File: Closure_11_TypeCheck_s.java    From coming with MIT License 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface() && functionType.isConstructor()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
          baseConstructor != null) {
        if (functionType.makesStructs() && !baseConstructor.makesStructs()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() &&
                   !baseConstructor.makesDicts()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }
    // Interface cannot implement any interfaces
    if (functionType.hasImplementedInterfaces()) {
      compiler.report(t.makeError(n,
          CONFLICTING_IMPLEMENTED_TYPE, functionPrivateName));
    }
    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        checkInterfaceConflictProperties(t, n, functionPrivateName,
            properties, currentProperties, interfaceType);
        properties.putAll(currentProperties);
      }
    }
  }
}
 
Example 18
Source File: Closure_125_TypeCheck_s.java    From coming with MIT License 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE)) {
        ObjectType proto = functionType.getPrototype();
        if (functionType.makesStructs() && !proto.isStruct()) {
          compiler.report(t.makeError(n, CONFLICTING_SHAPE_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() && !proto.isDict()) {
          compiler.report(t.makeError(n, CONFLICTING_SHAPE_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }

    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        checkInterfaceConflictProperties(t, n, functionPrivateName,
            properties, currentProperties, interfaceType);
        properties.putAll(currentProperties);
      }
    }
  }
}
 
Example 19
Source File: Closure_125_TypeCheck_t.java    From coming with MIT License 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE)) {
        ObjectType proto = functionType.getPrototype();
        if (functionType.makesStructs() && !proto.isStruct()) {
          compiler.report(t.makeError(n, CONFLICTING_SHAPE_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() && !proto.isDict()) {
          compiler.report(t.makeError(n, CONFLICTING_SHAPE_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }

    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        checkInterfaceConflictProperties(t, n, functionPrivateName,
            properties, currentProperties, interfaceType);
        properties.putAll(currentProperties);
      }
    }
  }
}
 
Example 20
Source File: Nopol2017_0029_s.java    From coming with MIT License 4 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) {
  FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType());
  String functionPrivateName = n.getFirstChild().getString();
  if (functionType.isConstructor()) {
    FunctionType baseConstructor = functionType.getSuperClassConstructor();
    if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) &&
        baseConstructor != null &&
        baseConstructor.isInterface()) {
      compiler.report(
          t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                      "constructor", functionPrivateName));
    } else {
      if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE)) {
        ObjectType proto = functionType.getPrototype();
        if (functionType.makesStructs() && !proto.isStruct()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "struct", functionPrivateName));
        } else if (functionType.makesDicts() && !proto.isDict()) {
          compiler.report(t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                                      "dict", functionPrivateName));
        }
      }
      // All interfaces are properly implemented by a class
      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);
        }
      }
      // check properties
      validator.expectAllInterfaceProperties(t, n, functionType);
    }
  } else if (functionType.isInterface()) {
    // Interface must extend only interfaces
    for (ObjectType extInterface : functionType.getExtendedInterfaces()) {
      if (extInterface.getConstructor() != null
          && !extInterface.getConstructor().isInterface()) {
        compiler.report(
            t.makeError(n, CONFLICTING_EXTENDED_TYPE,
                        "interface", functionPrivateName));
      }
    }

    // Check whether the extended interfaces have any conflicts
    if (functionType.getExtendedInterfacesCount() > 1) {
      // Only check when extending more than one interfaces
      HashMap<String, ObjectType> properties
          = new HashMap<String, ObjectType>();
      HashMap<String, ObjectType> currentProperties
          = new HashMap<String, ObjectType>();
      for (ObjectType interfaceType : functionType.getExtendedInterfaces()) {
        currentProperties.clear();
        checkInterfaceConflictProperties(t, n, functionPrivateName,
            properties, currentProperties, interfaceType);
        properties.putAll(currentProperties);
      }
    }
  }
}