(late reply - spam cop)
I agree that we should document it in the API if we return null.
(More generally, we should document
handling of interfaces generally - matching those types, declaring members
on them, matching
initializers, order of initialization, etc. But it's not clear to me
yet where that should go.)
The Signature interfaces aren't so elegant. It would be nice if there
was one for each kind of join point
and they used the same names as JoinPoint.getKind(). However,
removing getConstructor() from
InitializerSignature would be a binary-incompatible change, so we won't
make that change.
It would be runtime-incompatible to stop returning
InitializerSignature from an interface-initialization
join point. That could be ok if justified, but I don't think we
should create InterfaceInitializerSignature since
it's not a kind of join point nor is it a different signature
(syntactically) from class initializer.
Also if we do add StaticInitializerSignature it probably should not be a
CodeSignature since they
have no parameters or exceptions. But that again is a
runtime-incompatible change since we've been
returning InitializerSignature for static initialization. So we could
create StaticInitializerSignature as a
subinterface of InitializerSignature, and then document that it returns
empty arrays or null from *all*
of the methods (inherited from CodeSignature and
InitializerSignature). Oh joy! We could call it
EmptyInitializerSignature or NonConstructorInitializerSignature and use it
for both static initializers
and interface initializers, but yuck!
So avoiding making binary-incompatible changes I think forces us to return
null/empty values and
document them. Since the user can get the kind of the join point from
JoinPoint.StaticPart.getKind(),
s/he can distinguish static-initialization join points from initialization
join points, so there's no real
reason to create StaticInitializerSignature if/since it offers no
additional methods (and indeed, can't
implement the methods it inherits). The user can also check if
the declaring type is an interface
(JoinPoint.StaticPart.getSignature().getDeclaringType().isInterface()).
It might be a helpful static optimization to add boolean
JoinPoint.StaticPart.isDeclaringTypeInterface().
Some uses are:
- detecting initialization and staticinitialization of interfaces
- detecting whether a top-level implementation of a interface method was
defined in an aspect
But I'm not sure these underlie compelling use-cases. Does anyone
have more use-cases for this?
Also, it exposes what might be implementation-specific behaviors, and thus
to encourage
people to write programs that might not work in other implementations of
AspectJ.
Wes