1 11 12 package org.eclipse.jdt.apt.core.internal.declaration; 13 14 import java.util.Collections ; 15 import java.util.LinkedHashMap ; 16 import java.util.List ; 17 import java.util.Map ; 18 19 import org.eclipse.core.resources.IFile; 20 import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv; 21 import org.eclipse.jdt.apt.core.internal.util.Factory; 22 import org.eclipse.jdt.apt.core.internal.util.SourcePositionImpl; 23 import org.eclipse.jdt.core.dom.ASTNode; 24 import org.eclipse.jdt.core.dom.Annotation; 25 import org.eclipse.jdt.core.dom.CompilationUnit; 26 import org.eclipse.jdt.core.dom.IMethodBinding; 27 import org.eclipse.jdt.core.dom.IAnnotationBinding; 28 import org.eclipse.jdt.core.dom.IMemberValuePairBinding; 29 import org.eclipse.jdt.core.dom.ITypeBinding; 30 import org.eclipse.jdt.core.dom.IVariableBinding; 31 import org.eclipse.jdt.core.dom.MemberValuePair; 32 import org.eclipse.jdt.core.dom.Name; 33 import org.eclipse.jdt.core.dom.NormalAnnotation; 34 import org.eclipse.jdt.core.dom.SingleMemberAnnotation; 35 36 import com.sun.mirror.declaration.AnnotationMirror; 37 import com.sun.mirror.declaration.AnnotationTypeElementDeclaration; 38 import com.sun.mirror.declaration.AnnotationValue; 39 import com.sun.mirror.type.AnnotationType; 40 import com.sun.mirror.util.SourcePosition; 41 42 45 public class AnnotationMirrorImpl implements AnnotationMirror, EclipseMirrorObject 46 { 47 48 private final IAnnotationBinding _domAnnotation; 49 private final BaseProcessorEnv _env; 50 52 private final EclipseDeclarationImpl _annotated; 53 54 public AnnotationMirrorImpl(IAnnotationBinding annotationAstNode, EclipseDeclarationImpl decl, BaseProcessorEnv env) 55 { 56 _domAnnotation = annotationAstNode; 57 _env = env; 58 _annotated = decl; 59 assert _domAnnotation != null : "annotation node missing."; assert _annotated != null : "missing the declaration that is annotated with this annotation."; } 62 63 public AnnotationType getAnnotationType() 64 { 65 final ITypeBinding binding = _domAnnotation.getAnnotationType(); 66 if( binding == null ){ 67 final ASTNode node = _annotated.getCompilationUnit().findDeclaringNode(_domAnnotation); 68 String name = ""; if( node != null && node instanceof Annotation ){ 70 final Name typeNameNode = ((Annotation)node).getTypeName(); 71 if( typeNameNode != null ) 72 name = typeNameNode.toString(); 73 } 74 return Factory.createErrorAnnotationType(name); 75 } 76 else 77 return (AnnotationType)Factory.createReferenceType(binding, _env); 78 } 79 80 public Map <AnnotationTypeElementDeclaration, AnnotationValue> getElementValues() 81 { 82 final IMemberValuePairBinding[] pairs = _domAnnotation.getDeclaredMemberValuePairs(); 83 if (pairs.length == 0) { 84 return Collections.emptyMap(); 85 } 86 87 final Map <AnnotationTypeElementDeclaration, AnnotationValue> result = 88 new LinkedHashMap <AnnotationTypeElementDeclaration, AnnotationValue>(pairs.length * 4 / 3 + 1 ); 89 for( IMemberValuePairBinding pair : pairs ){ 90 final String name = pair.getName(); 91 if( name == null ) continue; 92 IMethodBinding elementMethod = pair.getMethodBinding(); 93 if( elementMethod != null ){ 94 final EclipseDeclarationImpl mirrorDecl = Factory.createDeclaration(elementMethod, _env); 95 if( mirrorDecl != null && mirrorDecl.kind() == EclipseMirrorObject.MirrorKind.ANNOTATION_ELEMENT ) 96 { 97 final AnnotationTypeElementDeclaration elementDecl = 98 (AnnotationTypeElementDeclaration)mirrorDecl; 99 final AnnotationValue annoValue = 100 Factory.createAnnotationMemberValue(pair.getValue(), name, this, _env, elementDecl.getReturnType()); 101 if( annoValue != null ) 102 result.put( elementDecl, annoValue); 103 } 104 } 105 } 106 return result; 107 } 108 109 public SourcePosition getPosition() 110 { 111 if( isFromSource() ){ 112 final CompilationUnit unit = _annotated.getCompilationUnit(); 113 final org.eclipse.jdt.core.dom.Annotation annotation = getAstNode(); 114 if( annotation == null ) return null; 115 org.eclipse.jdt.core.dom.ASTNode astNode = annotation.getTypeName(); 116 if( astNode == null ) 117 astNode = annotation; 118 119 final int offset = astNode.getStartPosition(); 120 return new SourcePositionImpl(astNode.getStartPosition(), 121 astNode.getLength(), 122 unit.getLineNumber(offset), 123 unit.getColumnNumber(offset), 124 _annotated); 125 } 126 return null; 127 } 128 129 public String toString() 130 { 131 return _domAnnotation.toString(); 132 } 133 134 141 public ITypeBinding[] getMemberValueTypeBinding(String membername) 142 { 143 if( membername == null ) return null; 144 final IMemberValuePairBinding[] declaredPairs = _domAnnotation.getDeclaredMemberValuePairs(); 145 for( IMemberValuePairBinding pair : declaredPairs ){ 146 if( membername.equals(pair.getName()) ){ 147 final Object value = pair.getValue(); 148 return getValueTypeBinding(value, pair.getMethodBinding().getReturnType()); 149 } 150 } 151 152 final IMethodBinding binding = getMethodBinding(membername); 154 if(binding == null ) return null; 155 final Object defaultValue = binding.getDefaultValue(); 156 if( defaultValue != null ) 157 return getValueTypeBinding(defaultValue, binding.getReturnType() ); 158 else 159 return null; 160 } 161 162 private ITypeBinding[] getValueTypeBinding(Object value, final ITypeBinding resolvedType) 163 { 164 if( value == null ) return null; 165 if( resolvedType.isPrimitive() || resolvedType.isAnnotation() || value instanceof String ) 166 return new ITypeBinding[]{ resolvedType }; 167 else if( resolvedType.isArray() ){ 168 final Object [] elements = (Object [])value; 169 final ITypeBinding[] result = new ITypeBinding[elements.length]; 170 final ITypeBinding leafType = resolvedType.getElementType(); 171 for(int i=0, len = elements.length; i<len; i++ ){ 172 final ITypeBinding[] t = getValueTypeBinding(elements[i], leafType); 173 result[i] = t == null ? null : t[0]; 174 } 175 return result; 176 } 177 else if( value instanceof IVariableBinding ) 178 return new ITypeBinding[]{ ( (IVariableBinding)value ).getDeclaringClass() }; 179 else if( value instanceof ITypeBinding ) 180 return new ITypeBinding[]{ (ITypeBinding)value }; 181 else 182 throw new IllegalStateException ("value = " + value + " resolvedType = " + resolvedType ); 184 } 185 186 190 public Object getValue(final String memberName) 191 { 192 if( memberName == null ) return null; 193 final IMemberValuePairBinding[] declaredPairs = _domAnnotation.getDeclaredMemberValuePairs(); 194 for( IMemberValuePairBinding pair : declaredPairs ){ 195 if( memberName.equals(pair.getName()) ){ 196 return pair.getValue(); 197 } 198 } 199 200 final IMethodBinding binding = getMethodBinding(memberName); 202 if(binding == null ) return null; 203 return binding.getDefaultValue(); 204 } 205 206 210 public IMethodBinding getMethodBinding(final String memberName) 211 { 212 if( memberName == null ) return null; 213 final ITypeBinding typeBinding = _domAnnotation.getAnnotationType(); 214 if( typeBinding == null ) return null; 215 final IMethodBinding[] methods = typeBinding.getDeclaredMethods(); 216 for( IMethodBinding method : methods ){ 217 if( memberName.equals(method.getName()) ) 218 return method; 219 } 220 return null; 221 } 222 223 public IAnnotationBinding getResolvedAnnotaion(){return _domAnnotation; } 224 225 226 227 public MirrorKind kind(){ return MirrorKind.ANNOTATION_MIRROR; } 228 229 boolean isFromSource() 230 { 231 return _annotated.isFromSource(); 232 } 233 234 org.eclipse.jdt.core.dom.Annotation getAstNode() 235 { 236 if( isFromSource() ){ 237 final CompilationUnit unit = _annotated.getCompilationUnit(); 238 final ASTNode node = unit.findDeclaringNode(_domAnnotation); 239 if( node instanceof org.eclipse.jdt.core.dom.Annotation ) 240 return (org.eclipse.jdt.core.dom.Annotation)node; 241 } 242 return null; 243 } 244 245 @SuppressWarnings ("unchecked") 246 ASTNode getASTNodeForElement(String name) 247 { 248 if( name == null ) return null; 249 final org.eclipse.jdt.core.dom.Annotation anno = getAstNode(); 250 if( anno != null ){ 251 if( anno.isSingleMemberAnnotation() ){ 252 if( "value".equals(name) ) return ((SingleMemberAnnotation)anno).getValue(); 254 } 255 else if( anno.isNormalAnnotation() ){ 256 final List <MemberValuePair> pairs = ((NormalAnnotation)anno).values(); 257 for( MemberValuePair pair : pairs ) 258 { 259 final String pairName = pair.getName() == null ? null : pair.getName().toString(); 260 if( name.equals(pairName) ) 261 return pair.getValue(); 262 } 263 } 264 } 265 return null; 267 } 268 269 CompilationUnit getCompilationUnit() { return _annotated.getCompilationUnit(); } 270 271 public BaseProcessorEnv getEnvironment(){ return _env; } 272 273 public IFile getResource() 274 { return _annotated.getResource(); } 275 276 public EclipseDeclarationImpl getAnnotatedDeclaration(){ return _annotated; } 277 278 public boolean equals(Object obj){ 279 if( obj instanceof AnnotationMirrorImpl ){ 280 return ((AnnotationMirrorImpl)obj)._domAnnotation == _domAnnotation; 281 } 282 return false; 283 } 284 285 public int hashCode(){ 286 return _domAnnotation.hashCode(); 287 } 288 } 289 | Popular Tags |