/** * Copyright (C) 2006-2017 INRIA and contributors * Spoon - http://spoon.gforge.inria.fr/ * * This software is governed by the CeCILL-C License under French law and * abiding by the rules of distribution of free software. You can use, modify * and/or redistribute the software under the terms of the CeCILL-C license as * circulated by CEA, CNRS and INRIA at http://www.cecill.info. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ package spoon.support.reflect.reference; import spoon.Launcher; import spoon.reflect.declaration.CtEnum; import spoon.reflect.declaration.CtField; import spoon.reflect.declaration.CtType; import spoon.reflect.declaration.CtVariable; import spoon.reflect.declaration.ModifierKind; import spoon.reflect.reference.CtFieldReference; import spoon.reflect.reference.CtTypeReference; import spoon.reflect.visitor.CtVisitor; import spoon.support.util.RtHelper; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Member; import java.util.Collections; import java.util.Set; public class CtFieldReferenceImpl<T> extends CtVariableReferenceImpl<T> implements CtFieldReference<T> { private static final long serialVersionUID = 1L; CtTypeReference<?> declaringType; boolean fina = false; boolean stat = false; public CtFieldReferenceImpl() { super(); } @Override public void accept(CtVisitor visitor) { visitor.visitCtFieldReference(this); } @Override public Member getActualField() { try { if (getDeclaringType().getActualClass().isAnnotation()) { return getDeclaringType().getActualClass().getDeclaredMethod( getSimpleName()); } return getDeclaringType().getActualClass().getDeclaredField( getSimpleName()); } catch (Exception e) { Launcher.LOGGER.error(e.getMessage(), e); } return null; } @Override protected AnnotatedElement getActualAnnotatedElement() { return (AnnotatedElement) getActualField(); } // @Override // public <A extends Annotation> A getAnnotation(Class<A> annotationType) { // A annotation = super.getAnnotation(annotationType); // if (annotation != null) { // return annotation; // } // // use reflection // Class<?> c = getDeclaringType().getActualClass(); // if (c.isAnnotation()) { // for (Method m : RtHelper.getAllMethods(c)) { // if (!getSimpleName().equals(m.getName())) { // continue; // } // m.setAccessible(true); // return m.getAnnotation(annotationType); // } // } else { // for (Field f : RtHelper.getAllFields(c)) { // if (!getSimpleName().equals(f.getName())) { // continue; // } // f.setAccessible(true); // return f.getAnnotation(annotationType); // } // } // return null; // } // @Override // public Annotation[] getAnnotations() { // Annotation[] annotations = super.getAnnotations(); // if (annotations != null) { // return annotations; // } // // use reflection // Class<?> c = getDeclaringType().getActualClass(); // for (Field f : RtHelper.getAllFields(c)) { // if (!getSimpleName().equals(f.getName())) { // continue; // } // f.setAccessible(true); // return f.getAnnotations(); // } // // If the fields belong to an annotation type, they are actually // // methods // for (Method m : RtHelper.getAllMethods(c)) { // if (!getSimpleName().equals(m.getName())) { // continue; // } // m.setAccessible(true); // return m.getAnnotations(); // } // return null; // } @Override @SuppressWarnings("unchecked") public CtField<T> getDeclaration() { return fromDeclaringType(); } private CtField<T> fromDeclaringType() { if (declaringType == null) { return null; } CtType<?> type = declaringType.getDeclaration(); if (type != null) { return (CtField<T>) type.getField(getSimpleName()); } return null; } @Override public CtField<T> getFieldDeclaration() { if (declaringType == null) { return null; } CtType<?> type = declaringType.getTypeDeclaration(); if (type != null) { final CtField<T> ctField = (CtField<T>) type.getField(getSimpleName()); if (ctField == null && type instanceof CtEnum) { return ((CtEnum) type).getEnumValue(getSimpleName()); } return ctField; } return null; } @Override public CtTypeReference<?> getDeclaringType() { return declaringType; } @Override public String getQualifiedName() { return getDeclaringType().getQualifiedName() + "#" + getSimpleName(); } @Override public boolean isFinal() { return fina; } /** * Tells if the referenced field is static. */ @Override public boolean isStatic() { return stat; } @Override public <C extends CtFieldReference<T>> C setDeclaringType(CtTypeReference<?> declaringType) { if (declaringType != null) { declaringType.setParent(this); } this.declaringType = declaringType; return (C) this; } @Override public <C extends CtFieldReference<T>> C setFinal(boolean b) { fina = b; return (C) this; } @Override public <C extends CtFieldReference<T>> C setStatic(boolean stat) { this.stat = stat; return (C) this; } @Override public Set<ModifierKind> getModifiers() { CtVariable<?> v = getDeclaration(); if (v != null) { return v.getModifiers(); } Member m = getActualField(); if (m != null) { return RtHelper.getModifiers(m.getModifiers()); } return Collections.emptySet(); } @Override public CtFieldReference<T> clone() { return (CtFieldReference<T>) super.clone(); } }