All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jdt.internal.compiler.apt.model.AnnotationValueImpl Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.apt.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.AnnotationValueVisitor;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;

import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.DoubleConstant;
import org.eclipse.jdt.internal.compiler.impl.FloatConstant;
import org.eclipse.jdt.internal.compiler.impl.LongConstant;
import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;

public class AnnotationValueImpl implements AnnotationValue, TypeIds {
	
	/*
	 * Additions to T_* constants in TypeIds. 
	 */
	private static final int T_AnnotationMirror = -1;
	private static final int T_EnumConstant = -2;
	private static final int T_ClassObject = -3;
	private static final int T_ArrayType = -4;
	
	private final BaseProcessingEnvImpl _env;
	
	/**
	 * The annotation value, as it would be returned by
	 * {@link #getValue()}.  For instance, an Integer (for an int
	 * constant), a VariableElement (for an enum constant), or
	 * a List containing multiple such (for an array type).  
	 */
	private final Object _value;
	
	/**
	 * The type stored in _value, represented as a T_* value from {@link TypeIds}
	 * or one of the additional T_* values defined in this class.
	 */
	private final int _kind;

	/**
	 * @param value
	 *            The JDT representation of a compile-time constant. See
	 *            {@link ElementValuePair#getValue()} for possible object types:
	 *            
    *
  • {@link org.eclipse.jdt.internal.compiler.impl.Constant} for member * of primitive type or String
  • *
  • {@link TypeBinding} for a member value of type * {@link java.lang.Class}
  • *
  • {@link FieldBinding} for an enum constant
  • *
  • {@link AnnotationBinding} for an annotation instance
  • *
  • Object[] for a member value of array type, where the * array entries are one of the above
  • *
* @param type * The JDT representation of the type of the constant, as determined * by the return type of the element. This is needed because the type * of the value may have been widened (e.g., byte to int) by the compiler * and we need to call the proper visitor. This is used only for base types. * If it is null or not a BaseTypeBinding, it is ignored and the type is * determined from the type of the value. */ public AnnotationValueImpl(BaseProcessingEnvImpl env, Object value, TypeBinding type) { _env = env; int kind[] = new int[1]; if (type == null) { _value = convertToMirrorType(value, type, kind); _kind = kind[0]; } else if (type.isArrayType()) { List convertedValues = null; TypeBinding valueType = ((ArrayBinding)type).elementsType(); if (value instanceof Object[]) { Object[] values = (Object[])value; convertedValues = new ArrayList(values.length); for (Object oneValue : values) { convertedValues.add(new AnnotationValueImpl(_env, oneValue, valueType)); } } else { convertedValues = new ArrayList(1); convertedValues.add(new AnnotationValueImpl(_env, value, valueType)); } _value = Collections.unmodifiableList(convertedValues); _kind = T_ArrayType; } else { _value = convertToMirrorType(value, type, kind); _kind = kind[0]; } } /** * Convert the JDT representation of a single constant into its javax.lang.model * representation. For instance, convert a StringConstant into a String, or * a FieldBinding into a VariableElement. This does not handle the case where * value is an Object[]. * @param value the JDT object * @param type the return type of the annotation member. If null or not a * BaseTypeBinding, this is ignored and the value is inspected to determine type. * @param kind an int array whose first element will be set to the type of the * converted object, represented with T_* values from TypeIds or from this class. * @return */ private Object convertToMirrorType(Object value, TypeBinding type, int kind[]) { if (type == null) { kind[0] = TypeIds.T_JavaLangString; return ""; //$NON-NLS-1$ } else if (type instanceof BaseTypeBinding || type.id == TypeIds.T_JavaLangString) { if (value == null) { if (type instanceof BaseTypeBinding || type.id == TypeIds.T_JavaLangString) { // return a string with error in it to reflect a value that could not be resolved kind[0] = TypeIds.T_JavaLangString; return ""; //$NON-NLS-1$ } else if (type.isAnnotationType()) { kind[0] = T_AnnotationMirror; return _env.getFactory().newAnnotationMirror(null); } } else if (value instanceof Constant) { if (type instanceof BaseTypeBinding) { kind[0] = ((BaseTypeBinding)type).id; } else if (type.id == TypeIds.T_JavaLangString) { kind[0] = ((Constant)value).typeID(); } else { // error case kind[0] = TypeIds.T_JavaLangString; return ""; //$NON-NLS-1$ } switch (kind[0]) { case T_boolean: return ((Constant)value).booleanValue(); case T_byte: return ((Constant)value).byteValue(); case T_char: return ((Constant)value).charValue(); case T_double: return ((Constant)value).doubleValue(); case T_float: return ((Constant)value).floatValue(); case T_int: try { if (value instanceof LongConstant || value instanceof DoubleConstant || value instanceof FloatConstant) { // error case kind[0] = TypeIds.T_JavaLangString; return ""; //$NON-NLS-1$ } return ((Constant)value).intValue(); } catch (ShouldNotImplement e) { kind[0] = TypeIds.T_JavaLangString; return ""; //$NON-NLS-1$ } case T_JavaLangString: return ((Constant)value).stringValue(); case T_long: return ((Constant)value).longValue(); case T_short: return ((Constant)value).shortValue(); } } } else if (type.isEnum()) { if (value instanceof FieldBinding) { kind[0] = T_EnumConstant; return (VariableElement) _env.getFactory().newElement((FieldBinding) value); } else { kind[0] = TypeIds.T_JavaLangString; return ""; //$NON-NLS-1$ } } else if (type.isAnnotationType()) { if (value instanceof AnnotationBinding) { kind[0] = T_AnnotationMirror; return _env.getFactory().newAnnotationMirror((AnnotationBinding) value); } } else if (value instanceof TypeBinding) { kind[0] = T_ClassObject; return _env.getFactory().newTypeMirror((TypeBinding) value); } // error case kind[0] = TypeIds.T_JavaLangString; return ""; //$NON-NLS-1$ } @SuppressWarnings("unchecked") // Need to cast Object _value to a List @Override public R accept(AnnotationValueVisitor v, P p) { switch (_kind) { case TypeIds.T_boolean: return v.visitBoolean((Boolean)_value, p); case TypeIds.T_byte: return v.visitByte((Byte)_value, p); case TypeIds.T_char: return v.visitChar((Character)_value, p); case TypeIds.T_double: return v.visitDouble((Double)_value, p); case TypeIds.T_float: return v.visitFloat((Float)_value, p); case TypeIds.T_int: return v.visitInt((Integer)_value, p); case TypeIds.T_JavaLangString: return v.visitString((String)_value, p); case TypeIds.T_long: return v.visitLong((Long)_value, p); case TypeIds.T_short: return v.visitShort((Short)_value, p); case T_EnumConstant: return v.visitEnumConstant((VariableElement)_value, p); case T_ClassObject: return v.visitType((TypeMirror)_value, p); case T_AnnotationMirror: return v.visitAnnotation((AnnotationMirror)_value, p); case T_ArrayType: return v.visitArray((List)_value, p); default: return null; } } @Override public Object getValue() { return _value; } @Override public boolean equals(Object obj) { if (obj instanceof AnnotationValueImpl) { return this._value.equals(((AnnotationValueImpl) obj)._value); } return false; } @Override public int hashCode() { return this._value.hashCode() + this._kind; } @Override public String toString() { if (null == _value) { return "null"; //$NON-NLS-1$ } return _value.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy