ValueComparison.cpp

00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2006-$THISYEAR$ $TROLLTECH$. All rights reserved.
00004 **
00005 ** This file is part of the $MODULE$ of the Qt Toolkit.
00006 **
00007 ** $TROLLTECH_DUAL_LICENSE$
00008 **
00009 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00010 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00011 **
00012 ***************************************************************************
00013 */
00014 
00015 #include "AtomicValue.h"
00016 #include "Boolean.h"
00017 #include "BuiltinTypes.h"
00018 #include "CommonSequenceTypes.h"
00019 #include "CommonValues.h"
00020 #include "OptimizationPasses.h"
00021 
00022 #include "ValueComparison.h"
00023 
00024 using namespace Patternist;
00025 
00026 ValueComparison::ValueComparison(const Expression::Ptr &op1,
00027                                  const AtomicComparator::Operator op,
00028                                  const Expression::Ptr &op2) : PairContainer(op1, op2),
00029                                                                m_operator(op)
00030 {
00031 }
00032 
00033 Item::Ptr ValueComparison::evaluateSingleton(const DynamicContext::Ptr &context) const
00034 {
00035     const Item::Ptr it1(m_operand1->evaluateSingleton(context));
00036     if(!it1)
00037         return Item::Ptr();
00038 
00039     const Item::Ptr it2(m_operand2->evaluateSingleton(context));
00040     if(!it2)
00041         return Item::Ptr();
00042 
00043     return Boolean::fromValue(flexibleCompare(it1, it2, context));
00044 }
00045 
00046 Expression::Ptr ValueComparison::typeCheck(const StaticContext::Ptr &context,
00047                                            const SequenceType::Ptr &reqType)
00048 {
00049     const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
00050     const ItemType::Ptr t1(m_operand1->staticType()->itemType());
00051     const ItemType::Ptr t2(m_operand2->staticType()->itemType());
00052     Q_ASSERT(t1);
00053     Q_ASSERT(t2);
00054 
00055     if(*CommonSequenceTypes::Empty == *t1 ||
00056        *CommonSequenceTypes::Empty == *t2)
00057     {
00058         return CommonValues::emptySequence;
00059     }
00060     else
00061     {
00062         prepareComparison(fetchComparator(t1, t2, context));
00063 
00064         return me;
00065     }
00066 }
00067 
00068 Expression::Ptr ValueComparison::compress(const StaticContext::Ptr &context)
00069 {
00070     const Expression::Ptr me(PairContainer::compress(context));
00071 
00072     if(me.get() != this)
00073         return me;
00074 
00075     if(isCaseInsensitiveCompare(m_operand1, m_operand2))
00076         useCaseInsensitiveComparator();
00077 
00078     return me;
00079 }
00080 
00081 bool ValueComparison::isCaseInsensitiveCompare(Expression::Ptr &op1, Expression::Ptr &op2)
00082 {
00083     Q_ASSERT(op1);
00084     Q_ASSERT(op2);
00085 
00086     const ID iD = op1->id();
00087 
00088     if((iD == IDLowerCaseFN || iD == IDUpperCaseFN) && iD == op2->id())
00089     {
00090         /* Both are either fn:lower-case() or fn:upper-case(). */
00091 
00092         /* Replace the calls to the functions with its operands. */
00093         op1 = op1->operands().first();
00094         op2 = op2->operands().first();
00095 
00096         return true;
00097     }
00098     else
00099         return false;
00100 }
00101 
00102 OptimizationPass::List ValueComparison::optimizationPasses() const
00103 {
00104     return OptimizationPasses::comparisonPasses;
00105 }
00106 
00107 SequenceType::List ValueComparison::expectedOperandTypes() const
00108 {
00109     SequenceType::List result;
00110     result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
00111     result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
00112     return result;
00113 }
00114 
00115 SequenceType::Ptr ValueComparison::staticType() const
00116 {
00117     if(m_operand1->staticType()->cardinality().allowsEmpty() ||
00118        m_operand2->staticType()->cardinality().allowsEmpty())
00119         return CommonSequenceTypes::ZeroOrOneBoolean;
00120     else
00121         return CommonSequenceTypes::ExactlyOneBoolean;
00122 }
00123 
00124 ExpressionVisitorResult::Ptr ValueComparison::accept(const ExpressionVisitor::Ptr &visitor) const
00125 {
00126     return visitor->visit(this);
00127 }
00128 
00129 Expression::ID ValueComparison::id() const
00130 {
00131     return IDValueComparison;
00132 }
00133 
00134 // vim: et:ts=4:sw=4:sts=4

Generated on Thu Feb 8 14:54:24 2007 for Patternist by  doxygen 1.5.1