Package nexj.core.persistence.operator

Source Code of nexj.core.persistence.operator.UnaryOperator

// Copyright 2010 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.persistence.operator;

import java.io.IOException;

import nexj.core.meta.Primitive;
import nexj.core.meta.Type;
import nexj.core.meta.TypeMismatchException;
import nexj.core.persistence.Operator;
import nexj.core.persistence.Query;
import nexj.core.scripting.Pair;
import nexj.core.util.PrintWriter;

/**
* Unary operator expression node.
*/
public abstract class UnaryOperator extends Operator
{
   // associations

   /**
    * The operand.
    */
   protected Operator m_operand;

   // operations

   /**
    * Sets the operand.
    * @param operand The operand to set. Can be null.
    * @return False if the operand is null.
    */
   public boolean setOperand(Operator operand)
   {
      m_operand = operand;

      if (operand == null)
      {
         return false;
      }

      operand.setParent(this);

      return true;
   }

   /**
    * @return The operand.
    */
   public Operator getOperand()
   {
      return m_operand;
   }

   /**
    * @see nexj.core.persistence.Operator#visit(nexj.core.persistence.Operator.Visitor, int)
    */
   public boolean visit(Visitor visitor, int nFlags)
   {
      if ((nFlags & VISIT_PREORDER) != 0)
      {
         if (!visitor.visit(this))
         {
            return false;
         }
      }

      if (m_operand != null)
      {
         if (visitor.isEligible(m_operand))
         {
            if (!m_operand.visit(visitor, nFlags))
            {
               return false;
            }
         }
      }

      if ((nFlags & VISIT_POSTORDER) != 0)
      {
         if (!visitor.visit(this))
         {
            return false;
         }
      }

      return true;
   }

   /**
    * @see nexj.core.persistence.Operator#normalize(int)
    */
   protected void normalizeOperand(int nFlags)
   {
      if ((nFlags & NORMALIZE_NORECUR) == 0)
      {
         m_operand = m_operand.normalize(nFlags);
      }

      setSource(m_operand.getSource(), nFlags);
   }

   /**
    * @see nexj.core.persistence.Operator#normalize(int)
    */
   public Operator normalize(int nFlags)
   {
      normalizeOperand(nFlags);

      Type type = m_operand.getType();

      if (type == null)
      {
         m_type = null;
         setConstantValue(null);
      }
      else if (type.isPrimitive())
      {
         ConversionMapper mapper = null;
         UnaryDescriptor descriptor = null;
         Primitive resultType = null;

         if (m_source != null)
         {
            mapper = m_source.getAdapter().getConversionMapper();
            descriptor = mapper.getUnaryDescriptor(this);
         }

         if (descriptor == null)
         {
            m_source = null;
            mapper = getConversionMapper();
            descriptor = mapper.getUnaryDescriptor(this);

            if (descriptor == null)
            {
               throw new TypeMismatchException(getSymbol());
            }
         }
         else
         {
            resultType = getConversionMapper().getUnaryDescriptor(this).getResultType();
         }

         if (mapper.getType((Primitive)type) != mapper.getType(descriptor.getOperandType()))
         {
            setOperand(new TypeConversionOperator(descriptor.getOperandType(), m_operand));
            m_operand = m_operand.normalize(nFlags | NORMALIZE_NORECUR);
         }

         m_type = descriptor.getResultType();

         if (m_operand.isConstant())
         {
            foldConstant();
         }

         if (m_source != null && mapper.getType((Primitive)m_type) != mapper.getType(resultType))
         {
            TypeConversionOperator result = new TypeConversionOperator(resultType, this);

            result.setParent(m_parent);
            m_parent = result;
            result.normalize(nFlags | NORMALIZE_NORECUR);

            return result;
         }
      }
      else
      {
         return normalizeMetaclass(nFlags);
      }

      return this;
   }

   /**
    * Normalizes a class attribute.
    * @see nexj.core.persistence.Operator#normalize(int)
    */
   protected Operator normalizeMetaclass(int nFlags)
   {
      throw new TypeMismatchException(getSymbol());
   }

   /**
    * Folds a constant value.
    */
   protected void foldConstant()
   {
      setConstantValue(evaluate());
   }

   /**
    * @see nexj.core.persistence.Operator#getExpression(nexj.core.persistence.Query)
    */
   public Object getExpression(Query root)
   {
      return Pair.list(getSymbol(), m_operand.getExpression(root));
   }

   /**
    * @see nexj.core.persistence.Operator#copy(nexj.core.persistence.Operator)
    */
   public void copy(Operator src)
   {
      super.copy(src);

      UnaryOperator op = (UnaryOperator)src;

      m_operand = op.m_operand;

      if (m_operand != null)
      {
         m_operand.setParent(this);
      }
   }

   /**
    * @see nexj.core.persistence.Operator#compareTo(java.lang.Object)
    */
   public int compareTo(Object obj)
   {
      int n = super.compareTo(obj);

      if (n != 0)
      {
         return n;
      }

      return m_operand.compareTo(((UnaryOperator)obj).getOperand());
   }

   /**
    * @see java.lang.Object#clone()
    */
   public Object clone()
   {
      UnaryOperator op = (UnaryOperator)super.clone();

      if (m_operand != null)
      {
         op.setOperand((Operator)m_operand.clone());
      }

      return op;
   }

   /**
    * @see nexj.core.util.Printable#printOn(PrintWriter)
    */
   public void printOn(PrintWriter writer) throws IOException
   {
      writer.write('(');
      writer.print(getSymbol());
      writer.write(' ');
      writer.print(m_operand);
      writer.write(')');
   }
}
TOP

Related Classes of nexj.core.persistence.operator.UnaryOperator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.