CompilationUnit
/**
* Finds the corresponding AST node in the given compilation unit from
* which the given binding originated. Returns null
if the
* binding does not correspond to any node in this compilation unit.
*
* This method always returns
* null
when the binding object comes from a different AST.
*
* @param instance the binding
* @return the corresponding node where the given binding is declared,
* or null
if the binding does not correspond to a node in this
* compilation unit or if bindings were not requested when this AST was built
* @see #findDeclaringNode(String)
*/
public ASTNode findDeclaringNode(IAnnotationInstance instance) {
return this.ast.getBindingResolver().findDeclaringNode(instance);
}
// seems like a heavy operation; only works if bindings asked for
// do we have precedent?
// missing spec
Annotation
public IAnnotationInstance resolveAnnotation()
{ return this.ast.getBindingResolver().resolveAnnotation(this); }
/**
* Represents an instance of JSR 175 Annotation.
*/
public interface IAnnotationInstance
{
/**
* Type of the annotation, which will always
* return true
to ITypeBinding.isAnnotation()
* @return the type of the annotation.
*/
ITypeBinding getAnnotationType();
/**
* @return the array of declared element value pair of the annotation.
*/
IElementValuePair[] getDeclaredElementValuePairs();
}
// should not be public (not API)
public class AnnotationInstance implements IAnnotationInstance
/**
* Represents an element value pair of an 175 Annotation instance.
*/
public interface IElementValuePair
{
/**
* @return the name of the member
*/
public String getName();
/**
* @return the method binding that defines this element value pair.
*/
public IMethodBinding getMethodBinding();
/**
* This will determine the type of object returned in the {@link #getElementValue()}
* @return the type of the element value.
*
*/
public ITypeBinding getElementType();
/**
* If {@link #getElementType()} returns a primitive type, the result is the box
* equivalent. (i.e. Integer
for type "int").
* Return String
if {@link #getElementType()} returns type String
* Return {@link ITypeBinding} if {@link #getElementType()} returns type Class
* Return {@link IVariableBinding} if {@link #getElementType()} returns an enum type.
* Return {@link IAnnotationInstance} if {@link #getElementType()} returns an annotation type.
* Return an Object
array if {@link #getElementType()} returns an array type.
*
* @return the compile-time constant of this element or null if none exists.
* Return null if bindings are not requested when the DOM/AST is built.
*/
public Object getElementValue();
}
// should not be public (not API)
public class ElementValuePair implements IElementValuePair
IMethodBinding
/**
* Return the annotations annotating this method/constructor.
* The behavior of this API is the same regardless of whether
* this is a parameterized method or not.
*
* @return the annotations annotating this method/costructor.
*/
public IAnnotationInstance[] getAnnotations();
/**
* Return the annotations of a parameter of this method.
* The behavior of this API is the same regardless of whether
* this is a parameterized method or not.
*
* @param paramIndex the index of the parameter of interest.
* @return the annotations of the paramIndex
th parameter
* @throws ArrayIndexOutOfBoundsException if paramIndex
is
* not a valid index.
*/
public IAnnotationInstance[] getParameterAnnotations(int paramIndex);
/**
* Return whether this binding is for an annotation method.
*
* @return true
iff this is the binding for an annotation method
* and false
otherwise.
*/
public boolean isAnnotationMethod();
/**
* Return the default value of an annotation method, iff this method
* binding represents an annotation method that has a default value.
* Return null
otherwise.
*
*
* If the type of the value is a primitive type, the result is the boxed equivalent
* (i.e., int returned as an Integer
). If the type of the value is
* String
, the result is the string itself. If the type of the value
* is an enum type, IVariableBinding
is returned. If the type of the
* value is an annotation type, IAnnotationInstance
is returned.
* If the type of the value is an array, then an one-dimensional array will be
* returned. If there are not defaulta value, the result is null
.
*
*
* @return the default value of an annotation method. Return null
* if one does not exist or if this binding is not an annotation method binding.
* This will also return null
if no binding information is requested
* when this DOM/AST is built.
*
*/
public Object getDefaultValue();
ITypeBinding
/**
* Return the annotations iff one of {@link #isAnnotation()}, {@link #isEnum},
* {@link #isClass} or {@link #isInterface()} returns true
.
* Return null otherwise.
*
* @return the annotations annotating the type if it is a reference type.
* Return null otherwise.
* @see #isAnnotation()
* @see #isEnum()
* @see #isClass()
* @see #isInterface()
* @since 3.1
*/
public IAnnotationInstance[] getAnnotations();
IVariableBinding
/**
* Return the annotations annotating this variable if {@link #isField()} or
* {@link #isEnumConstant()} return true
or this binding
* is a parameter.
* If this is a field, the behavior of this API is the same regardless of whether
* it is parameterized or not.
*
* @return the annotations of this variable iff it is a field, an enum constant
* or an parameter. Return null
otherwise.
* @see #isEnumConstant()
* @see #isField()
* @since 3.1
*/
public IAnnotationInstance[] getAnnotations();
// issue return empty array instead of null
====================================
Theodora, I've reviewed the DOM API portion of the patch. I believe the proposed API additions will
give client the access they need to annotation. I have some suggested renamings and minor improvements.
public interface IResolvedAnnotation
ITypeBinding getAnnotationType();
IResolvedMemberValuePair[] getDeclaredMemberValuePairs();
IResolvedMemberValuePair[] getAllMemberValuePairs();
- rename from IAnnotationInstance
to suggest it is resolved info like bindings
- add getAllMemberValuePairs to return implicit defaulted pairs as well
public interface IResolvedMemberValuePair
public String getName();
public IMethodBinding getMemberBinding();
public Object getValue();
- rename from IElementValuePair to suggest it is resolved info like bindings
- rename getElementValue -> getValue for consistency with MemberValuePair.getValue
- rename getMethodBinding -> getMemberBinding
- delete getElementType; unnecessary; client can do getMemberBinding().getResultType()
Annotation
public IResolvedAnnotation resolveAnnotation();
CompilationUnit
public ASTNode findDeclaringNode(IResolvedAnnotation resolvedAnnotation) {
- fine as proposed
IBinding
public IResolvedAnnotation[] getAnnotations();
- pull method up from ITypeBinding, IVariableBinding, IMethodBinding so that package annotations are exposed as well
- change spec to return empty list rather than null, to make it more convenient for clients
IMethodBinding
public IResolvedAnnotation[] getParameterAnnotations(int paramIndex);
public boolean isAnnotationMember();
public Object getDefaultValue();
- rename
isAnnotationMethod -> isAnnotationMember
for greater consistency (
the node type is named AnnotationTypeMember)
I'm attaching a patch for the o.e.jdt.core/dom subtree only (APT branch)
with fleshed out specs for everything.
Some of the other things I noticed
- all new API must be tagged with @since and have full specs.
I didn't know what Philippe and you have discussed, so I marked all the new
classes and method
@since 3.2 on the assumption that they will appear only on 3.2.
- since there is new API involved, the test suites will need to be upgraded as well to include
comprehensive tests for the new API elements
- the implementation classes AnnotationInstance and ElementValuePair are public; since these
are not intended to be exposed as API, then should to be package-private
- it would help if the code formatting followed the same conventions used elsewhere in the code
=================
ITypeBinding
IMethodBinding
IVariableBinding
public IAnnotationInstance[] getAnnotations();
- needs to cover package bindings as well, which also carry annotations
- move method up to IBinding
- should never return null; empty list is better
public class AnnotationInstance implements AnnotationInstance
public class ElementValuePair implements IElementValuePair
- neither of these are intented to be API classes
- should not be public
IMethodBinding
public boolean isAnnotationMethod();
- JLS3 terminology is annotation type member
- rename to isAnnotationTypeMember
IElementValuePair
- structural node is called MemberValuePair
public IMethodBinding getMethodBinding();
- rename to getAnnotationTypeMemberBinding
- new API requires new test suites