if (!(accessorElement instanceof PropertyAccessorElement)) {
return false;
}
PropertyAccessorElement propertyAccessorElement = (PropertyAccessorElement) accessorElement;
PropertyAccessorElement counterpartAccessor = null;
ClassElement enclosingClassForCounterpart = null;
if (propertyAccessorElement.isGetter()) {
counterpartAccessor = propertyAccessorElement.getCorrespondingSetter();
} else {
counterpartAccessor = propertyAccessorElement.getCorrespondingGetter();
// If the setter and getter are in the same enclosing element, return, this prevents having
// MISMATCHED_GETTER_AND_SETTER_TYPES reported twice.
if (counterpartAccessor != null
&& counterpartAccessor.getEnclosingElement() == propertyAccessorElement.getEnclosingElement()) {
return false;
}
}
if (counterpartAccessor == null) {
// If the accessor is declared in a class, check the superclasses.
if (enclosingClass != null) {
// Figure out the correct identifier to lookup in the inheritance graph, if 'x', then 'x=',
// or if 'x=', then 'x'.
String lookupIdentifier = propertyAccessorElement.getName();
if (StringUtilities.endsWithChar(lookupIdentifier, '=')) {
lookupIdentifier = lookupIdentifier.substring(0, lookupIdentifier.length() - 1);
} else {
lookupIdentifier += "=";
}
// lookup with the identifier.
ExecutableElement elementFromInheritance = inheritanceManager.lookupInheritance(
enclosingClass,
lookupIdentifier);
// Verify that we found something, and that it is an accessor
if (elementFromInheritance != null
&& elementFromInheritance instanceof PropertyAccessorElement) {
enclosingClassForCounterpart = (ClassElement) elementFromInheritance.getEnclosingElement();
counterpartAccessor = (PropertyAccessorElement) elementFromInheritance;
}
}
if (counterpartAccessor == null) {
return false;
}
}
// Default of null == no accessor or no type (dynamic)
Type getterType = null;
Type setterType = null;
// Get an existing counterpart accessor if any.
if (propertyAccessorElement.isGetter()) {
getterType = getGetterType(propertyAccessorElement);
setterType = getSetterType(counterpartAccessor);
} else if (propertyAccessorElement.isSetter()) {
setterType = getSetterType(propertyAccessorElement);
getterType = getGetterType(counterpartAccessor);
}
// If either types are not assignable to each other, report an error (if the getter is null,
// it is dynamic which is assignable to everything).
if (setterType != null && getterType != null && !getterType.isAssignableTo(setterType)) {
if (enclosingClassForCounterpart == null) {
errorReporter.reportTypeErrorForNode(
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
accessorDeclaration,
accessorTextName,
setterType,
getterType);
return true;
} else {
errorReporter.reportTypeErrorForNode(
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,
accessorDeclaration,
accessorTextName,
setterType,
getterType,
enclosingClassForCounterpart.getDisplayName());
}
}
return false;
}