blob: 1a8664fe6a0430fccfb20521790fbc5a1f7ba7ae [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 BEA Systems, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* wharley@bea.com - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.compiler.apt.tests.processors.inherited;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;
/**
* A processor that tests the dispatch functionality in the presence of annotations that are
* @Inherited. To enable this processor, add
* -Aorg.eclipse.jdt.compiler.apt.tests.processors.inherited.InheritedAnnoProc to the command line.
*
* @since 3.3
*/
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedOptions("org.eclipse.jdt.compiler.apt.tests.processors.inherited.InheritedAnnoProc")
public class InheritedAnnoProc extends BaseProcessor
{
// Initialized in collectElements:
private TypeElement _inheritedAnno;
private TypeElement _notInheritedAnno;
private TypeElement _elementA;
private TypeElement _elementAChild;
private TypeElement _elementANotAnnotated;
private TypeElement _elementAIntf;
private TypeElement _elementAEnum;
private Element _elementAi;
private Element _elementAfoo;
private Element _elementAinit; // c'tor with no param
private Element _elementAinitI; // c'tor with int param
private Element _elementAa; // method with c'tor-like name
private TypeElement _elementB;
private TypeElement _elementBChild;
private TypeElement _elementBNotAnnotated;
private Element _elementBfoo;
private Element _elementBi;
// Always return false from this processor, because it supports "*".
// The return value does not signify success or failure!
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
{
if (roundEnv.processingOver()) {
return false;
}
Map<String, String> options = processingEnv.getOptions();
if (!options.containsKey(this.getClass().getName())) {
// Disable this processor unless we are intentionally performing the test.
return false;
}
if (!collectElements()) {
return false;
}
if (!examineGetRootElements(roundEnv)) {
return false;
}
if (!examineGetElementsAnnotatedWith(roundEnv)) {
return false;
}
reportSuccess();
return false;
}
private boolean collectElements() {
_inheritedAnno = _elementUtils.getTypeElement("org.eclipse.jdt.compiler.apt.tests.annotations.InheritedAnno");
_notInheritedAnno = _elementUtils.getTypeElement("NotInheritedAnno");
if (null == _inheritedAnno || null == _notInheritedAnno) {
reportError("collectElements: Couldn't load annotation type");
return false;
}
_elementA = _elementUtils.getTypeElement("InheritanceA");
for (Element e : _elementA.getEnclosedElements()) {
String name = e.getSimpleName().toString();
if ("AChild".equals(name)) {
_elementAChild = (TypeElement)e;
}
else if ("ANotAnnotated".equals(name)) {
_elementANotAnnotated = (TypeElement)e;
}
else if ("AIntf".equals(name)) {
_elementAIntf = (TypeElement)e;
}
else if ("AEnum".equals(name)) {
_elementAEnum = (TypeElement)e;
}
else if ("i".equals(name)) {
_elementAi = e;
}
else if ("foo".equals(name)) {
_elementAfoo = e;
}
else if ("InheritanceA".equals(name)) {
_elementAa = e;
}
else if ("<init>".equals(name)) {
if (((ExecutableElement)e).getParameters().isEmpty()) {
_elementAinit = e;
}
else {
_elementAinitI = e;
}
}
}
if (null == _elementA || null == _elementAChild || null == _elementANotAnnotated ||
null == _elementAi || null == _elementAfoo || null == _elementAinitI || null == _elementAa ||
null == _elementAIntf || null == _elementAEnum || null == _elementAinit) {
reportError("collectElements: couldn't load elements from InheritanceA");
return false;
}
_elementB = _elementUtils.getTypeElement("InheritanceB");
for (Element e : _elementB.getEnclosedElements()) {
String name = e.getSimpleName().toString();
if ("BChild".equals(name)) {
_elementBChild = (TypeElement)e;
}
else if ("BNotAnnotated".equals(name)) {
_elementBNotAnnotated = (TypeElement)e;
}
else if ("i".equals(name)) {
_elementBi = e;
}
else if ("foo".equals(name)) {
_elementBfoo = e;
}
}
if (null == _elementB || null == _elementBChild || null == _elementBNotAnnotated ||
null == _elementBi || null == _elementBfoo) {
reportError("collectElements: couldn't load elements from InheritanceB");
return false;
}
return true;
}
/**
* Test the getRootElements implementation.
* @param roundEnv
* @return true if tests passed
*/
private boolean examineGetRootElements(RoundEnvironment roundEnv)
{
// Expect to see all elements (unaffected by presence of @Inherited)
final Element[] expected = {_notInheritedAnno, _elementA, _elementB};
Set<? extends Element> elements = new HashSet<Element>(roundEnv.getRootElements());
for (Element element : expected) {
if (!elements.remove(element)) {
reportError("examineRootElements: root elements did not contain expected element " + element.getSimpleName());
return false;
}
}
if (!elements.isEmpty()) {
reportError("examineRootElements: root elements contained unexpected elements " + elements);
return false;
}
return true;
}
private boolean examineGetElementsAnnotatedWith(RoundEnvironment roundEnv)
{
// Elements we expect to get from getElementsAnnotatedWith(@InheritedAnno)
final Element[] expectedInherited =
{ _elementA, _elementAChild, _elementAIntf, _elementAEnum,
_elementAi, _elementAfoo, _elementAinit, _elementAinitI, _elementAa,
_elementB, _elementBChild };
Set<? extends Element> actualInherited = new HashSet<Element>(roundEnv.getElementsAnnotatedWith(_inheritedAnno));
for (Element element : expectedInherited) {
if (!actualInherited.remove(element)) {
reportError("examineGetElementsAnnotatedWith(@InheritedAnno): did not contain expected element " + element.getSimpleName());
return false;
}
}
if (!actualInherited.isEmpty()) {
reportError("examineGetElementsAnnotatedWith(@InheritedAnno): contained unexpected elements " + actualInherited);
return false;
}
// Elements we expect to get from getElementsAnnotatedWith(@NotInheritedAnno)
final Element[] expectedNotInherited =
{ _elementA, _elementAChild, _elementAIntf, _elementAEnum,
_elementAi, _elementAfoo, _elementAinit, _elementAinitI, _elementAa };
Set<? extends Element> actualNotInherited = new HashSet<Element>(roundEnv.getElementsAnnotatedWith(_notInheritedAnno));
for (Element element : expectedNotInherited) {
if (!actualNotInherited.remove(element)) {
reportError("examineGetElementsAnnotatedWith(@NotInheritedAnno): did not contain expected element " + element.getSimpleName());
return false;
}
}
if (!actualNotInherited.isEmpty()) {
reportError("examineGetElementsAnnotatedWith(@NotInheritedAnno): contained unexpected elements " + actualNotInherited);
return false;
}
return true;
}
}