diff options
Diffstat (limited to 'weaver')
-rw-r--r-- | weaver/src/org/aspectj/weaver/ResolvedTypeX.java | 70 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/WeaverMessages.java | 2 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/weaver-messages.properties | 1 |
3 files changed, 59 insertions, 14 deletions
diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java index c9e95c5f3..67a96e072 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java @@ -975,31 +975,75 @@ public abstract class ResolvedTypeX extends TypeX { collector.addAll(getInterTypeMungers()); } + /** - * Check that we don't have any abstract type mungers unless this - * type is abstract. + * Check: + * 1) That we don't have any abstract type mungers unless this type is abstract. + * 2) That an abstract ITDM on an interface is declared public. (Compiler limitation) (PR70794) */ public void checkInterTypeMungers() { if (isAbstract()) return; + boolean itdProblem = false; + for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) { - ConcreteTypeMunger element = (ConcreteTypeMunger) iter.next(); - if (element.getSignature() != null && element.getSignature().isAbstract()) { - ISourceLocation xtraLocation = element.getSourceLocation(); - if (xtraLocation == null) { - // Until intertype mungers remember where they came from, the source location - // for the element is null when binary weaving. In these cases uses the - // source location for the aspect containing the ITD - xtraLocation = element.getAspectType().getSourceLocation(); - } + ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next(); + itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2 + + } + + if (itdProblem) return; // If the rules above are broken, return right now + + for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) { + ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next(); + if (munger.getSignature() != null && munger.getSignature().isAbstract()) { // Rule 1 world.getMessageHandler().handleMessage( - new Message("must implement abstract inter-type declaration: " + element.getSignature(), + new Message("must implement abstract inter-type declaration: " + munger.getSignature(), "", IMessage.ERROR, getSourceLocation(), null, - new ISourceLocation[] { xtraLocation })); + new ISourceLocation[] { getMungerLocation(munger) })); } } } + + /** + * See PR70794. This method checks that if an abstract inter-type method declaration is made on + * an interface then it must also be public. + * This is a compiler limitation that could be made to work in the future (if someone + * provides a worthwhile usecase) + * + * @return indicates if the munger failed the check + */ + private boolean checkAbstractDeclaration(ConcreteTypeMunger munger) { + if (munger.getMunger()!=null && (munger.getMunger() instanceof NewMethodTypeMunger)) { + ResolvedMember itdMember = munger.getSignature(); + ResolvedTypeX onType = itdMember.getDeclaringType().resolve(world); + if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) { + world.getMessageHandler().handleMessage( + new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE,munger.getSignature(),onType),"", + Message.ERROR,getSourceLocation(),null, + new ISourceLocation[]{getMungerLocation(munger)}) + ); + return true; + } + } + return false; + } + + /** + * Get a source location for the munger. + * Until intertype mungers remember where they came from, the source location + * for the munger itself is null. In these cases use the + * source location for the aspect containing the ITD. + * + */ + private ISourceLocation getMungerLocation(ConcreteTypeMunger munger) { + ISourceLocation sloc = munger.getSourceLocation(); + if (sloc == null) { + sloc = munger.getAspectType().getSourceLocation(); + } + return sloc; + } /** * Returns a ResolvedTypeX object representing the declaring type of this type, or diff --git a/weaver/src/org/aspectj/weaver/WeaverMessages.java b/weaver/src/org/aspectj/weaver/WeaverMessages.java index 8fe792f9b..ced85c507 100644 --- a/weaver/src/org/aspectj/weaver/WeaverMessages.java +++ b/weaver/src/org/aspectj/weaver/WeaverMessages.java @@ -53,7 +53,7 @@ public class WeaverMessages { public static final String ITD_CONFLICT = "itdConflict"; public static final String ITD_MEMBER_CONFLICT = "itdMemberConflict"; public static final String ITD_NON_EXPOSED_IMPLEMENTOR = "itdNonExposedImplementor"; - + public static final String ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE = "itdAbstractMustBePublicOnInterface"; public static final String NON_VOID_RETURN = "nonVoidReturn"; public static final String INCOMPATIBLE_RETURN_TYPE="incompatibleReturnType"; diff --git a/weaver/src/org/aspectj/weaver/weaver-messages.properties b/weaver/src/org/aspectj/weaver/weaver-messages.properties index c731fb965..febd44ff7 100644 --- a/weaver/src/org/aspectj/weaver/weaver-messages.properties +++ b/weaver/src/org/aspectj/weaver/weaver-messages.properties @@ -52,6 +52,7 @@ overridingStatic={0} cannot override {1}; overriding method is static itdConflict=intertype declaration from {0} conflicts with intertype declaration: {1} from {2} itdMemberConflict=inter-type declaration from {0} conflicts with existing member: {1} itdNonExposedImplementor=type {0} must be accessible for weaving interface inter type declaration from aspect {1} +itdAbstractMustBePublicOnInterface=abstract intertype method declaration ''{0}'' on interface {1} must be declared public (compiler limitation) # advice messages... nonVoidReturn=applying to join point that doesn't return void: {0} |