1 11 package org.eclipse.jdt.internal.compiler.apt.dispatch; 12 13 import java.lang.annotation.Annotation ; 14 import java.util.Collections ; 15 import java.util.HashSet ; 16 import java.util.Set ; 17 18 import javax.annotation.processing.RoundEnvironment; 19 import javax.lang.model.element.Element; 20 import javax.lang.model.element.ElementKind; 21 import javax.lang.model.element.TypeElement; 22 import javax.lang.model.util.ElementFilter; 23 24 import org.eclipse.jdt.internal.compiler.apt.model.Factory; 25 import org.eclipse.jdt.internal.compiler.apt.model.TypeElementImpl; 26 import org.eclipse.jdt.internal.compiler.apt.util.ManyToMany; 27 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; 28 import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding; 29 import org.eclipse.jdt.internal.compiler.lookup.Binding; 30 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 31 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 32 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 33 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; 34 import org.eclipse.jdt.internal.compiler.lookup.TagBits; 35 36 public class RoundEnvImpl implements RoundEnvironment 37 { 38 private final BaseProcessingEnvImpl _processingEnv; 39 private final boolean _isLastRound; 40 private final CompilationUnitDeclaration[] _units; 41 private final ManyToMany<TypeElement, Element> _annoToUnit; 42 private final ReferenceBinding[] _binaryTypes; 43 private final Factory _factory; 44 private Set <Element> _rootElements = null; 45 46 public RoundEnvImpl(CompilationUnitDeclaration[] units, ReferenceBinding[] binaryTypeBindings, boolean isLastRound, BaseProcessingEnvImpl env) { 47 _processingEnv = env; 48 _isLastRound = isLastRound; 49 _units = units; 50 _factory = _processingEnv.getFactory(); 51 52 AnnotationDiscoveryVisitor visitor = new AnnotationDiscoveryVisitor(_processingEnv); 54 if (_units != null) { 55 for (CompilationUnitDeclaration unit : _units) { 56 unit.traverse(visitor, unit.scope); 57 } 58 } 59 _annoToUnit = visitor._annoToElement; 60 if (binaryTypeBindings != null) collectAnnotations(binaryTypeBindings); 61 _binaryTypes = binaryTypeBindings; 62 } 63 64 private void collectAnnotations(ReferenceBinding[] referenceBindings) { 65 for (ReferenceBinding referenceBinding : referenceBindings) { 66 AnnotationBinding[] annotationBindings = referenceBinding.getAnnotations(); 68 for (AnnotationBinding annotationBinding : annotationBindings) { 69 TypeElement anno = (TypeElement)_factory.newElement(annotationBinding.getAnnotationType()); 70 Element element = _factory.newElement(referenceBinding); 71 _annoToUnit.put(anno, element); 72 } 73 FieldBinding[] fieldBindings = referenceBinding.fields(); 74 for (FieldBinding fieldBinding : fieldBindings) { 75 annotationBindings = fieldBinding.getAnnotations(); 76 for (AnnotationBinding annotationBinding : annotationBindings) { 77 TypeElement anno = (TypeElement)_factory.newElement(annotationBinding.getAnnotationType()); 78 Element element = _factory.newElement(fieldBinding); 79 _annoToUnit.put(anno, element); 80 } 81 } 82 MethodBinding[] methodBindings = referenceBinding.methods(); 83 for (MethodBinding methodBinding : methodBindings) { 84 annotationBindings = methodBinding.getAnnotations(); 85 for (AnnotationBinding annotationBinding : annotationBindings) { 86 TypeElement anno = (TypeElement)_factory.newElement(annotationBinding.getAnnotationType()); 87 Element element = _factory.newElement(methodBinding); 88 _annoToUnit.put(anno, element); 89 } 90 } 91 ReferenceBinding[] memberTypes = referenceBinding.memberTypes(); 92 collectAnnotations(memberTypes); 93 } 94 } 95 96 102 public Set <TypeElement> getRootAnnotations() 103 { 104 return Collections.unmodifiableSet(_annoToUnit.getKeySet()); 105 } 106 107 @Override  108 public boolean errorRaised() 109 { 110 return _processingEnv.errorRaised(); 111 } 112 113 119 @Override  120 public Set <? extends Element> getElementsAnnotatedWith(TypeElement a) 121 { 122 if (a.getKind() != ElementKind.ANNOTATION_TYPE) { 123 throw new IllegalArgumentException ("Argument must represent an annotation type"); } 125 Binding annoBinding = ((TypeElementImpl)a)._binding; 126 if (0 != (annoBinding.getAnnotationTagBits() & TagBits.AnnotationInherited)) { 127 Set <Element> annotatedElements = new HashSet <Element>(_annoToUnit.getValues(a)); 128 ReferenceBinding annoTypeBinding = (ReferenceBinding)((TypeElementImpl)a)._binding; 131 for (TypeElement element : ElementFilter.typesIn(getRootElements())) { 132 ReferenceBinding typeBinding = (ReferenceBinding)((TypeElementImpl)element)._binding; 133 addAnnotatedElements(annoTypeBinding, typeBinding, annotatedElements); 134 } 135 return Collections.unmodifiableSet(annotatedElements); 136 } 137 return Collections.unmodifiableSet(_annoToUnit.getValues(a)); 138 } 139 140 147 private void addAnnotatedElements(ReferenceBinding anno, ReferenceBinding type, Set <Element> result) { 148 if (type.isClass()) { 149 if (inheritsAnno(type, anno)) { 150 result.add(_factory.newElement(type)); 151 } 152 } 153 for (ReferenceBinding element : type.memberTypes()) { 154 addAnnotatedElements(anno, element, result); 155 } 156 } 157 158 164 private boolean inheritsAnno(ReferenceBinding element, ReferenceBinding anno) { 165 do { 166 AnnotationBinding[] annos = element.getAnnotations(); 167 for (AnnotationBinding annoBinding : annos) { 168 if (annoBinding.getAnnotationType() == anno) { 169 return true; 171 } 172 } 173 } while (null != (element = element.superclass())); 174 return false; 175 } 176 177 @Override  178 public Set <? extends Element> getElementsAnnotatedWith(Class <? extends Annotation > a) 179 { 180 String canonicalName = a.getCanonicalName(); 181 if (canonicalName == null) { 182 throw new IllegalArgumentException ("Argument must represent an annotation type"); } 185 TypeElement annoType = _processingEnv.getElementUtils().getTypeElement(canonicalName); 186 return getElementsAnnotatedWith(annoType); 187 } 188 189 @Override  190 public Set <? extends Element> getRootElements() 191 { 192 if (_units == null) { 193 return Collections.emptySet(); 194 } 195 if (_rootElements == null) { 196 Set <Element> elements = new HashSet <Element>(_units.length); 197 for (CompilationUnitDeclaration unit : _units) { 198 if (null == unit.scope || null == unit.scope.topLevelTypes) 199 continue; 200 for (SourceTypeBinding binding : unit.scope.topLevelTypes) { 201 Element element = _factory.newElement(binding); 202 if (null == element) { 203 throw new IllegalArgumentException ("Top-level type binding could not be converted to element: " + binding); } 205 elements.add(element); 206 } 207 } 208 if (this._binaryTypes != null) { 209 for (ReferenceBinding typeBinding : _binaryTypes) { 210 TypeElement element = (TypeElement)_factory.newElement(typeBinding); 211 if (null == element) { 212 throw new IllegalArgumentException ("Top-level type binding could not be converted to element: " + typeBinding); } 214 elements.add(element); 215 } 216 } 217 _rootElements = elements; 218 } 219 return _rootElements; 220 } 221 222 @Override  223 public boolean processingOver() 224 { 225 return _isLastRound; 226 } 227 228 } 229 | Popular Tags |