Expression::Ptr FunctionCall::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType) { /* We don't cache properties() at some stages because it can be invalidated * by the typeCheck(). */ const FunctionSignature::Arity maxArgs = signature()->maximumArguments(); /* We do this before the typeCheck() such that the appropriate conversions * are applied to the ContextItem. */ if(m_operands.count() < maxArgs && has(UseContextItem)) { m_operands.append(Expression::Ptr(new ContextItem())); context->addLocation(m_operands.last().data(), context->locationFor(this)); } const Expression::Ptr me(UnlimitedContainer::typeCheck(context, reqType)); if(me.data() != this) return me; const Properties props(properties()); if((props & RewriteToEmptyOnEmpty) == RewriteToEmptyOnEmpty && *CommonSequenceTypes::Empty == *m_operands.first()->staticType()->itemType()) { return EmptySequence::create(this, context); } if((props & LastOperandIsCollation) == LastOperandIsCollation && m_operands.count() == maxArgs) { m_operands.last() = Expression::Ptr(new CollationChecker(m_operands.last())); context->addLocation(m_operands.last().data(), context->locationFor(this)); } return me; }
Expression::Ptr DocumentFN::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType) { /* See the class documentation for the rewrite that we're doing here. */ /* Generate type checking code for our operands such that they match. */ typeCheckOperands(context); const QSourceLocation myLocation(context->locationFor(this)); const FunctionFactory::Ptr functions(context->functionSignatures()); Expression::Ptr uriSource; { Expression::List distinctValuesArgs; distinctValuesArgs.append(m_operands.first()); uriSource = functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::distinct_values), distinctValuesArgs, context, this); context->addLocation(uriSource.data(), myLocation); } const VariableSlotID rangeSlot = context->allocateRangeSlot(); const Expression::Ptr uriReference(new RangeVariableReference(uriSource, rangeSlot)); context->addLocation(uriReference.data(), myLocation); Expression::List docArgs; if(m_operands.count() == 2) { Expression::List baseUriArgs; baseUriArgs.append(uriReference); baseUriArgs.append(m_operands.at(1)); const Expression::Ptr fnBaseUri(functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::resolve_uri), baseUriArgs, context, this)); context->addLocation(fnBaseUri.data(), myLocation); docArgs.append(fnBaseUri); } else docArgs.append(uriReference); const Expression::Ptr fnDoc(functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::doc), docArgs, context, this)); context->addLocation(fnDoc.data(), myLocation); Expression::Ptr newMe(new ForClause(rangeSlot, uriSource, fnDoc, -1 /* We have no position variable. */)); Expression::Ptr oldMe(this); rewrite(oldMe, newMe, context); return newMe->typeCheck(context, reqType); }