// already.
if (hasUnknownOrEmptySupertype(ctorType)) {
return;
}
FunctionType superClass = ctorType.getSuperClassConstructor();
boolean superClassHasProperty = superClass != null &&
superClass.getInstanceType().hasProperty(propertyName);
boolean superClassHasDeclaredProperty = superClass != null &&
superClass.getInstanceType().isPropertyTypeDeclared(propertyName);
// For interface
boolean superInterfaceHasProperty = false;
boolean superInterfaceHasDeclaredProperty = false;
if (ctorType.isInterface()) {
for (ObjectType interfaceType : ctorType.getExtendedInterfaces()) {
superInterfaceHasProperty =
superInterfaceHasProperty ||
interfaceType.hasProperty(propertyName);
superInterfaceHasDeclaredProperty =
superInterfaceHasDeclaredProperty ||
interfaceType.isPropertyTypeDeclared(propertyName);
}
}
boolean declaredOverride = info != null && info.isOverride();
boolean foundInterfaceProperty = false;
if (ctorType.isConstructor()) {
for (JSType implementedInterface :
ctorType.getAllImplementedInterfaces()) {
if (implementedInterface.isUnknownType() ||
implementedInterface.isEmptyType()) {
continue;
}
FunctionType interfaceType =
implementedInterface.toObjectType().getConstructor();
Preconditions.checkNotNull(interfaceType);
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
&& !superClassHasProperty
&& !superInterfaceHasProperty) {
// nothing to do here, it's just a plain new property
return;
}
ObjectType topInstanceType = superClassHasDeclaredProperty ?
superClass.getTopMostDefiningType(propertyName) : null;
boolean declaredLocally =
ctorType.isConstructor() &&
(ctorType.getPrototype().hasOwnProperty(propertyName) ||
ctorType.getInstanceType().hasOwnProperty(propertyName));
if (reportMissingOverride.isOn()
&& !declaredOverride
&& superClassHasDeclaredProperty
&& declaredLocally) {
// @override not present, but the property does override a superclass
// property
compiler.report(t.makeError(n, reportMissingOverride,
HIDDEN_SUPERCLASS_PROPERTY, propertyName,
topInstanceType.toString()));
}
// @override is present and we have to check that it is ok
if (superClassHasDeclaredProperty) {
// there is a superclass implementation
JSType superClassPropType =
superClass.getInstanceType().getPropertyType(propertyName);
TemplateTypeMap ctorTypeMap =
ctorType.getTypeOfThis().getTemplateTypeMap();
if (!ctorTypeMap.isEmpty()) {
superClassPropType = superClassPropType.visit(
new TemplateTypeMapReplacer(typeRegistry, ctorTypeMap));
}
if (!propertyType.isSubtype(superClassPropType)) {
compiler.report(
t.makeError(n, HIDDEN_SUPERCLASS_PROPERTY_MISMATCH,
propertyName, topInstanceType.toString(),
superClassPropType.toString(), propertyType.toString()));
}
} else if (superInterfaceHasDeclaredProperty) {
// there is an super interface property
for (ObjectType interfaceType : ctorType.getExtendedInterfaces()) {
if (interfaceType.hasProperty(propertyName)) {
JSType superPropertyType =
interfaceType.getPropertyType(propertyName);
if (!propertyType.isSubtype(superPropertyType)) {
topInstanceType = interfaceType.getConstructor().
getTopMostDefiningType(propertyName);
compiler.report(
t.makeError(n, HIDDEN_SUPERCLASS_PROPERTY_MISMATCH,
propertyName, topInstanceType.toString(),
superPropertyType.toString(),