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

jadex.javaparser.javaccimpl.CastNode Maven / Gradle / Ivy

package jadex.javaparser.javaccimpl;

import jadex.commons.IValueFetcher;
import jadex.commons.SReflect;


/**
 *  Node representing a cast expression.
 *  A cast node has two children: a type node
 *  representing the static type of the cast,
 *  and an expression, representing the value to cast.
 */
// Todo: Allow casts between basic number types.
public class CastNode	extends ExpressionNode
{
	//-------- constructors --------

	/**
	 *  Create an expression node.
	 *  @param p	The parser.
	 *  @param id	The id.
	 */
	public CastNode(ParserImpl p, int id)
	{
		super(p, id);
	}

	//-------- evaluation --------

	/**
	 *  Precompute the static type and check if cast is possible.
	 */
	public void precompile()
	{
		ExpressionNode	type	= (ExpressionNode)jjtGetChild(0);
		ExpressionNode	expression	= (ExpressionNode)jjtGetChild(1);

		// Precompute type of cast.
		if(type.isConstant())
		{
			try
			{
				setStaticType((Class)type.getValue(null));
			}
			catch(Exception e)
			{
			}
		}

		// This node is constant, when the subnodes are constant.
		if(type.isConstant() && expression.isConstant())
		{
			try
			{
				setConstantValue(getValue(null));
				setConstant(true);
			}
			catch(Exception e)
			{
			}
		}
	}

	/**
	 *  Evaluate the expression in the given state
	 *  with respect to given parameters.
	 * @param params	The parameters (string, value pairs), if any.
	 *  @return	The value of the term.
	 */
	public Object	getValue(IValueFetcher fetcher) //throws Exception
	{
		// For not constant nodes we have to typecheck each evaluation.
		if(!isConstant())
		{
			Object	value	= ((ExpressionNode)jjtGetChild(1)).getValue(fetcher);

			// Only non-null values have to be checked.
			if(value!=null)
			{
				// Get type, if not static.
				Class	type;
				if(getStaticType()!=null)
				{
					type	= getStaticType();
				}
				else
				{
					type	= (Class)((ExpressionNode)jjtGetChild(0)).getValue(null);
				}

				// Check if cast is possible.
				if(!SReflect.isSupertype(type, value.getClass())
					&& SReflect.isSupertype(Number.class, type)
					&& value instanceof Number)
				{
					// Perform number conversion with precision loss
					// should print warning???
					type	= SReflect.getWrappedType(type);
					if(type==Float.class)
					{
						value	= Float.valueOf(((Number)value).floatValue());
					}
					else if(type==Long.class)
					{
						value	= Long.valueOf(((Number)value).longValue());
					}
					else if(type==Integer.class)
					{
						value	= Integer.valueOf(((Number)value).intValue());
					}
					else if(type==Short.class)
					{
						value	= Short.valueOf(((Number)value).shortValue());
					}
					else if(type==Byte.class)
					{
						value	= Byte.valueOf(((Number)value).byteValue());
					}
					else if(type==Character.class)
					{
						value	= Character.valueOf((char)((Number)value).intValue());
					}
				}
				else if(!SReflect.isSupertype(type, value.getClass()))
				{
					throw new ClassCastException(value.toString()
						+" cannot be cast to "+type.getName());
				}
			}
			return value;
		}

		// For constant nodes typecheck has been performed by first evaluation.
		else
		{
			return getConstantValue();
		}
	}

	/**
	 *  Create a string representation of this node and its subnodes.
	 *  @return A string representation of this node.
	 */
	public String toPlainString()
	{
		// Have to add braces ???
		return "(("+jjtGetChild(0).toPlainString()+")" + jjtGetChild(1).toPlainString()+")";
	}
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy