private void checkSuperProperty(
RawNominalType current, NominalType superType, String pname,
Multimap<String, DeclaredFunctionType> propMethodTypesToProcess,
Multimap<String, JSType> propTypesToProcess) {
JSType inheritedPropType = superType.getPropDeclaredType(pname);
if (inheritedPropType == null) {
// No need to go further for undeclared props.
return;
}
Collection<PropertyDef> inheritedPropDefs;
if (superType.isInterface()) {
inheritedPropDefs = getPropDefsFromInterface(superType, pname);
} else {
inheritedPropDefs =
ImmutableSet.of(getPropDefFromClass(superType, pname));
}
if (superType.isInterface() && current.isClass() &&
!current.mayHaveProp(pname)) {
warnings.add(JSError.make(
inheritedPropDefs.iterator().next().defSite,
TypeValidator.INTERFACE_METHOD_NOT_IMPLEMENTED,
pname, superType.toString(), current.toString()));
return;
}
PropertyDef localPropDef = propertyDefs.get(current, pname);
JSType localPropType = localPropDef == null ? null :
current.getInstancePropDeclaredType(pname);
if (localPropDef != null && superType.isClass() &&
localPropType.getFunType() != null &&
superType.hasConstantProp(pname)) {
// TODO(dimvar): This doesn't work for multiple levels in the hierarchy.
// Clean up how we process inherited properties and then fix this.
warnings.add(JSError.make(
localPropDef.defSite, CANNOT_OVERRIDE_FINAL_METHOD, pname));
return;
}
// System.out.println("nominalType: " + current + "'s " + pname +
// " localPropType: " + localPropType +
// " with super: " + superType +
// " inheritedPropType: " + inheritedPropType);
if (localPropType == null) {
// Add property from interface to class
propTypesToProcess.put(pname, inheritedPropType);
} else if (!localPropType.isSubtypeOf(inheritedPropType)) {
warnings.add(JSError.make(
localPropDef.defSite, INVALID_PROP_OVERRIDE, pname,
inheritedPropType.toString(), localPropType.toString()));
} else if (localPropDef.methodType != null) {
// If we are looking at a method definition, munging may be needed
for (PropertyDef inheritedPropDef : inheritedPropDefs) {
if (inheritedPropDef.methodType != null) {
propMethodTypesToProcess.put(pname, inheritedPropDef.methodType);