if (typePattern == TypePattern.NO) {
return null; // already had an error here
}
// isWildChild = (child instanceof WildTypePattern);
UnresolvedType iType = typePattern.getExactType();
ResolvedType parentType = iType.resolve(world);
if (targetType.equals(world.getCoreType(UnresolvedType.OBJECT))) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.DECP_OBJECT), this.getSourceLocation(), null);
return null;
}
// Ensure the target doesn't already have an
// alternate parameterization of the generic type on it
if (parentType.isParameterizedType() || parentType.isRawType()) {
// Let's take a look at the parents we already have
boolean isOK = verifyNoInheritedAlternateParameterization(targetType, parentType, world);
if (!isOK) {
return null;
}
}
if (parentType.isAssignableFrom(targetType)) {
return null; // already a parent
}
// Enum types that are targetted for decp through a wild type pattern get linted
if (reportErrors && isWildChild && targetType.isEnum()) {
world.getLint().enumAsTargetForDecpIgnored.signal(targetType.toString(), getSourceLocation());
}
// Annotation types that are targetted for decp through a wild type pattern get linted
if (reportErrors && isWildChild && targetType.isAnnotation()) {
world.getLint().annotationAsTargetForDecpIgnored.signal(targetType.toString(), getSourceLocation());
}
// 1. Can't use decp to make an enum/annotation type implement an interface
if (targetType.isEnum() && parentType.isInterface()) {
if (reportErrors && !isWildChild) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ENUM_TO_IMPL_INTERFACE,
targetType), getSourceLocation(), null);
}
return null;
}
if (targetType.isAnnotation() && parentType.isInterface()) {
if (reportErrors && !isWildChild) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ANNOTATION_TO_IMPL_INTERFACE,
targetType), getSourceLocation(), null);
}
return null;
}
// 2. Can't use decp to change supertype of an enum/annotation
if (targetType.isEnum() && parentType.isClass()) {
if (reportErrors && !isWildChild) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ENUM_TO_EXTEND_CLASS,
targetType), getSourceLocation(), null);
}
return null;
}
if (targetType.isAnnotation() && parentType.isClass()) {
if (reportErrors && !isWildChild) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_ON_ANNOTATION_TO_EXTEND_CLASS,
targetType), getSourceLocation(), null);
}
return null;
}
// 3. Can't use decp to declare java.lang.Enum/java.lang.annotation.Annotation as the parent of a type
if (parentType.getSignature().equals(UnresolvedType.ENUM.getSignature())) {
if (reportErrors && !isWildChild) {
world.showMessage(IMessage.ERROR, WeaverMessages
.format(WeaverMessages.CANT_DECP_TO_MAKE_ENUM_SUPERTYPE, targetType), getSourceLocation(), null);
}
return null;
}
if (parentType.getSignature().equals(UnresolvedType.ANNOTATION.getSignature())) {
if (reportErrors && !isWildChild) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_DECP_TO_MAKE_ANNOTATION_SUPERTYPE,
targetType), getSourceLocation(), null);
}
return null;
}
if (parentType.isAssignableFrom(targetType)) {
return null; // already a parent
}
if (targetType.isAssignableFrom(parentType)) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_EXTEND_SELF, targetType.getName()), this
.getSourceLocation(), null);
return null;
}
if (parentType.isClass()) {
if (targetType.isInterface()) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.INTERFACE_CANT_EXTEND_CLASS), this
.getSourceLocation(), null);
return null;
// how to handle xcutting errors???
}
if (!targetType.getSuperclass().isAssignableFrom(parentType)) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.DECP_HIERARCHY_ERROR, iType.getName(),
targetType.getSuperclass().getName()), this.getSourceLocation(), null);
return null;
} else {
return parentType;
}