Expression::Ptr ElementConstructor::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType) { /* What does this code do? When type checking our children, our namespace * bindings, which are also children of the form of NamespaceConstructor * instances, must be statically in-scope for them, so find them and * shuffle their bindings into the StaticContext. */ m_staticBaseURI = context->baseURI(); /* Namespace declarations changes the in-scope bindings, so let's * first lookup our child NamespaceConstructors. */ const ID operandID = m_operand2->id(); NamespaceResolver::Bindings overrides; if(operandID == IDExpressionSequence) { const Expression::List operands(m_operand2->operands()); const int len = operands.count(); for(int i = 0; i < len; ++i) { if(operands.at(i)->is(IDNamespaceConstructor)) { const QXmlName &nb = operands.at(i)->as<NamespaceConstructor>()->namespaceBinding(); overrides.insert(nb.prefix(), nb.namespaceURI()); } } } const NamespaceResolver::Ptr newResolver(new DelegatingNamespaceResolver(context->namespaceBindings(), overrides)); const StaticContext::Ptr augmented(new StaticNamespaceContext(newResolver, context)); return PairContainer::typeCheck(augmented, reqType); }
Expression::Ptr ElementConstructor::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType) { m_staticBaseURI = context->baseURI(); /* Namespace declarations changes the in-scope bindings, so let's * first lookup our child NamespaceConstructors. */ const ID operandID = m_operand2->id(); NamespaceResolver::Bindings overrides; if(operandID == IDExpressionSequence) { const Expression::List operands(m_operand2->operands()); const int len = operands.count(); for(int i = 0; i < len; ++i) { if(operands.at(i)->is(IDNamespaceConstructor)) { const QXmlName &nb = operands.at(i)->as<NamespaceConstructor>()->namespaceBinding(); overrides.insert(nb.prefix(), nb.namespaceURI()); } } } const NamespaceResolver::Ptr newResolver(new DelegatingNamespaceResolver(context->namespaceBindings(), overrides)); const StaticContext::Ptr augmented(new StaticNamespaceContext(newResolver, context)); return PairContainer::typeCheck(augmented, reqType); }
Expression::Ptr OrderBy::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType) { m_returnOrderBy->setStay(true); /* It's important we do the typeCheck() before calling OrderSpec::prepare(), since * atomizers must first be inserted. */ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType)); const Expression::List ops(m_returnOrderBy->operands()); const int len = ops.count(); Q_ASSERT(ops.count() > 1); Q_ASSERT(m_orderSpecs.count() == ops.count() - 1); for(int i = 1; i < len; ++i) m_orderSpecs[i - 1].prepare(ops.at(i), context); return me; /* It's not meaningful to sort a single item or less, so rewrite ourselves * away if that is the case. This is an optimization. */ /* TODO: How do we remove ReturnOrderBy? if(Cardinality::zeroOrOne().isMatch(m_operand->staticType()->cardinality())) return m_operand->typeCheck(context, reqType); else return SingleContainer::typeCheck(context, reqType); */ }
void TripleContainer::setOperands(const Expression::List &ops) { Q_ASSERT(ops.count() == 3); m_operand1 = ops.first(); m_operand2 = ops.at(1); m_operand3 = ops.at(2); }