Expression::Ptr PatternPlatform::compress(const StaticContext::Ptr &context) { const Expression::Ptr me(FunctionCall::compress(context)); if(me != this) return me; if(m_operands.at(1)->is(IDStringValue)) { const DynamicContext::Ptr dynContext(context->dynamicContext()); m_pattern = parsePattern(m_operands.at(1)->evaluateSingleton(dynContext).stringValue(), dynContext); m_compiledParts |= PatternPrecompiled; } const Expression::Ptr flagOperand(m_operands.value(m_flagsPosition)); if(!flagOperand) { m_flags = NoFlags; m_compiledParts |= FlagsPrecompiled; } else if(flagOperand->is(IDStringValue)) { const DynamicContext::Ptr dynContext(context->dynamicContext()); m_flags = parseFlags(flagOperand->evaluateSingleton(dynContext).stringValue(), dynContext); m_compiledParts |= FlagsPrecompiled; } if(m_compiledParts == FlagsAndPattern) applyFlags(m_flags, m_pattern); return me; }
Expression::Ptr AndExpression::compress(const StaticContext::Ptr &context) { const Expression::Ptr newMe(PairContainer::compress(context)); if(newMe != this) return newMe; /* Both operands mustn't be evaluated in order to be able to compress. */ if(m_operand1->isEvaluated() && !m_operand1->evaluateEBV(context->dynamicContext())) return wrapLiteral(CommonValues::BooleanFalse, context, this); else if(m_operand2->isEvaluated() && !m_operand2->evaluateEBV(context->dynamicContext())) return wrapLiteral(CommonValues::BooleanFalse, context, this); else return Expression::Ptr(this); }
Expression::Ptr Expression::constantPropagate(const StaticContext::Ptr &context) const { Q_ASSERT(context); /* Optimization: We rewrite literals to literals here, which is pointless. * Maybe we should have a property which says "doesn't disable elimination * but don't eliminate me." */ if(staticType()->cardinality().allowsMany()) { Item::Iterator::Ptr it(evaluateSequence(context->dynamicContext())); Item::List result; Item item(it->next()); while(item) { result.append(item); item = it->next(); } switch(result.count()) { case 0: return EmptySequence::create(this, context); case 1: return rewrite(Expression::Ptr(new Literal(result.first())), context); default: return rewrite(Expression::Ptr(new LiteralSequence(result)), context); } } else { const Item item(evaluateSingleton(context->dynamicContext())); if(item) return rewrite(Expression::Ptr(new Literal(item)), context); else return EmptySequence::create(this, context); } }
Expression::Ptr ReplaceFN::compress(const StaticContext::Ptr &context) { const Expression::Ptr me(PatternPlatform::compress(context)); if(me != this) return me; if(m_operands.at(2)->is(IDStringValue)) { const int capt = captureCount(); if(capt == -1) return me; else m_replacementString = parseReplacement(captureCount(), context->dynamicContext()); } return me; }
Expression::Ptr DocFN::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType) { /* See the doxygen documentation for this function for the explanation * to why this implementation is here, as opposed to in * qsequencegeneratingfns.cpp. */ Q_ASSERT(context); prepareStaticBaseURI(context); const Expression::Ptr uriOp(m_operands.first()); if(!uriOp->isEvaluated()) return Expression::Ptr(FunctionCall::typeCheck(context, reqType)); const Item uriItem(uriOp->evaluateSingleton(context->dynamicContext())); if(!uriItem) return EmptySequence::create(this, context)->typeCheck(context, reqType); // TODO test this /* These two lines were previously in a separate function but are now duplicated * in DocFN::evaluateSingleton(), as part of a workaround for solaris-cc-64. */ const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(uriItem.stringValue(), context, this)); const QUrl uri(context->resolveURI(mayRela, staticBaseURI())); /* The URI is supplied statically, so, let's try to be clever. */ Q_ASSERT_X(context->resourceLoader(), Q_FUNC_INFO, "No resource loader is set in the StaticContext."); m_type = context->resourceLoader()->announceDocument(uri, ResourceLoader::MayUse); if(m_type) { Q_ASSERT(CommonSequenceTypes::ZeroOrOneDocumentNode->matches(m_type)); return Expression::Ptr(FunctionCall::typeCheck(context, reqType)); } else { context->error(QtXmlPatterns::tr("It will not be possible to retrieve %1.").arg(formatURI(uri)), ReportContext::FODC0002, this); return Expression::Ptr(); } }
Expression::Ptr IfThenClause::compress(const StaticContext::Ptr &context) { const Expression::Ptr me(TripleContainer::compress(context)); if(me != this) return me; /* All operands mustn't be evaluated in order for const folding to * be possible. Let's see how far we get. */ if(m_operand1->isEvaluated()) { if(m_operand1->evaluateEBV(context->dynamicContext())) return m_operand2; else return m_operand3; } else return me; }
Expression::Ptr NormalizeUnicodeFN::compress(const StaticContext::Ptr &context) { const Expression::Ptr me(FunctionCall::compress(context)); if(me != this) return me; Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2); if(m_operands.count() == 1) m_normForm = QString::NormalizationForm_C; else if(m_operands.last()->is(IDStringValue)) { m_normForm = static_cast<QString::NormalizationForm>( determineNormalizationForm(context->dynamicContext())); if(m_normForm == -1) return m_operands.first(); /* Remove the operand since we don't need it anymore. */ m_operands.removeLast(); } return me; }