| /******************************************************************************* |
| * 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.typemirror; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.annotation.processing.RoundEnvironment; |
| import javax.annotation.processing.SupportedAnnotationTypes; |
| import javax.annotation.processing.SupportedSourceVersion; |
| import javax.lang.model.SourceVersion; |
| import javax.lang.model.element.ElementKind; |
| import javax.lang.model.element.TypeElement; |
| import javax.lang.model.element.VariableElement; |
| import javax.lang.model.type.DeclaredType; |
| import javax.lang.model.type.TypeKind; |
| import javax.lang.model.type.TypeMirror; |
| import javax.lang.model.util.ElementFilter; |
| |
| import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor; |
| |
| /** |
| * A processor that explores the "model" target hierarchy with an emphasis |
| * on exploring the TypeMirror APIs. To enable this processor, add |
| * -Aorg.eclipse.jdt.compiler.apt.tests.processors.typemirror.TypeMirrorProc |
| * to the command line. |
| * @since 3.3 |
| */ |
| @SupportedAnnotationTypes("*") |
| @SupportedSourceVersion(SourceVersion.RELEASE_6) |
| public class TypeMirrorProc extends BaseProcessor |
| { |
| // Initialized in collectElements() |
| private TypeElement _elementAC; |
| private TypeElement _elementF; |
| private TypeElement _elementFChild; |
| private TypeMirror _typeString; |
| private TypeMirror _typeNumber; |
| |
| // 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()) { |
| // We're not interested in the postprocessing round. |
| 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 (!examineGetEnclosingType()) { |
| return false; |
| } |
| |
| if (!examineGetTypeArguments()) { |
| return false; |
| } |
| |
| reportSuccess(); |
| return false; |
| } |
| |
| /** |
| * Collect some elements that will be reused in various tests |
| * @return true if all tests passed |
| */ |
| private boolean collectElements() { |
| _elementF = _elementUtils.getTypeElement("targets.model.pc.F"); |
| if (_elementF == null || _elementF.getKind() != ElementKind.CLASS) { |
| reportError("element F was not found or was not a class"); |
| return false; |
| } |
| _elementFChild = _elementUtils.getTypeElement("targets.model.pc.F.FChild"); |
| if (_elementFChild == null || _elementFChild.getKind() != ElementKind.CLASS) { |
| reportError("element FChild was not found or was not a class"); |
| return false; |
| } |
| _elementAC = _elementUtils.getTypeElement("targets.model.pb.AC"); |
| if (_elementAC == null || _elementAC.getKind() != ElementKind.CLASS) { |
| reportError("element AC was not found or was not a class"); |
| return false; |
| } |
| |
| TypeElement e = _elementUtils.getTypeElement("java.lang.String"); |
| _typeString = e.asType(); |
| e = _elementUtils.getTypeElement("java.lang.Number"); |
| _typeNumber = e.asType(); |
| return true; |
| } |
| |
| /** |
| * Examine the DeclaredType.getEnclosingType() implementation |
| * @return true if all tests passed |
| */ |
| private boolean examineGetEnclosingType() { |
| TypeMirror outer = _elementF.asType(); |
| if (!(outer instanceof DeclaredType)) { |
| reportError("F.asType() did not return a DeclaredType"); |
| return false; |
| } |
| TypeMirror inner = _elementFChild.asType(); |
| if (!(outer instanceof DeclaredType)) { |
| reportError("F.FChild.asType() did not return a DeclaredType"); |
| return false; |
| } |
| TypeMirror innerParent = ((DeclaredType)inner).getEnclosingType(); |
| if (!_typeUtils.isSameType(outer, innerParent)) { |
| reportError("Enclosing type of FChild (" + innerParent + ") is not F (" + outer + ")"); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Examine the DeclaredType.getTypeArguments() implementation |
| * @return true if all tests passed |
| */ |
| private boolean examineGetTypeArguments() { |
| VariableElement fieldMapStringNumber = null; |
| VariableElement fieldRawList = null; |
| for (VariableElement field : ElementFilter.fieldsIn(_elementAC.getEnclosedElements())) { |
| String name = field.getSimpleName().toString(); |
| if ("_fieldMapStringNumber".equals(name)) { |
| fieldMapStringNumber = field; |
| } |
| else if ("_fieldRawList".equals(name)) { |
| fieldRawList = field; |
| } |
| } |
| if (null == fieldMapStringNumber || fieldMapStringNumber.getKind() != ElementKind.FIELD) { |
| reportError("Unable to find field AC._fieldMapStringNumber"); |
| return false; |
| } |
| if (null == fieldRawList || fieldRawList.getKind() != ElementKind.FIELD) { |
| reportError("Unable to find field AC._fieldRawList"); |
| return false; |
| } |
| TypeMirror typeMap = fieldMapStringNumber.asType(); |
| if (typeMap == null || typeMap.getKind() != TypeKind.DECLARED) { |
| reportError("Field AC._fieldMapStringNumber was not found or had wrong type kind"); |
| return false; |
| } |
| TypeMirror typeRawList = fieldRawList.asType(); |
| if (typeRawList == null || typeRawList.getKind() != TypeKind.DECLARED) { |
| reportError("Field AC._fieldRawList was not found or had wrong type kind"); |
| return false; |
| } |
| List<? extends TypeMirror> args = ((DeclaredType)typeMap).getTypeArguments(); |
| if (args == null || args.size() != 2) { |
| reportError("AC._fieldMapStringNumber.asType().getTypeArguments() returned wrong number of args: " + args); |
| return false; |
| } |
| Iterator<? extends TypeMirror> argsIterator = args.iterator(); |
| if (!_typeUtils.isSameType(_typeString, argsIterator.next()) || |
| !_typeUtils.isSameType(_typeNumber, argsIterator.next())) { |
| reportError("AC._fieldMapStringNumber.asType().getTypeArguments() returned wrong args: " + args); |
| return false; |
| } |
| args = ((DeclaredType)typeRawList).getTypeArguments(); |
| if (args == null || args.size() != 0) { |
| reportError("AC._fieldRawList.asType().getTypeArguments() returned wrong number of args: " + args); |
| return false; |
| } |
| |
| return true; |
| } |
| } |