void inspect(ASTNode *node, std::tr1::shared_ptr<QueryScope> scope, SimpleDTD const &dtd) { switch (node->getType()) { case ASTNode::NAVIGATION: { cout << "Type NAVIGATION" << endl; XQNav *nav = reinterpret_cast<XQNav*>(node); XQNav::Steps steps(nav->getSteps()); for (XQNav::Steps::const_iterator it = steps.begin(); it != steps.end(); ++it) inspect(it->step, scope, dtd); break; } case ASTNode::LITERAL: cout << "Type LITERAL" << endl; break; case ASTNode::NUMERIC_LITERAL: cout << "Type NUMERIC_LITERAL" << endl; break; case ASTNode::QNAME_LITERAL: cout << "Type QNAME_LITERAL" << endl; break; case ASTNode::SEQUENCE: cout << "Type SEQUENCE" << endl; break; case ASTNode::FUNCTION: { cout << "Type FUNCTION" << endl; XQFunction *fun = reinterpret_cast<XQFunction *>(node); VectorOfASTNodes const &args(fun->getArguments()); for (VectorOfASTNodes::const_iterator it = args.begin(); it != args.end(); ++it) inspect(*it, scope, dtd); break; } case ASTNode::VARIABLE: cout << "Type VARIABLE" << endl; break; case ASTNode::STEP: { XQStep *step = reinterpret_cast<XQStep*>(node); NodeTest *test = step->getNodeTest(); // Wild cards have no element name. if (test->getNameWildcard()) { scope->setNodeName("*"); return; } char *nodeType = XMLString::transcode(test->getNodeType()); char *nodeName = XMLString::transcode(test->getNodeName()); if (strcmp(nodeType, "element") == 0) { // Test to see if this element is allowed here if (!dtd.allowElement(nodeName, scope->nodeName())) cerr << "The element " << nodeName << " is not allowed inside " << scope->nodeName() << endl; scope->setNodeName(nodeName); } else if (strcmp(nodeType, "attribute") == 0) { if (!dtd.allowAttribute(nodeName, scope->nodeName())) cerr << "The attribute " << nodeName << " is not allowed inside " << scope->nodeName() << endl; } delete[] nodeType; delete[] nodeName; break; } case ASTNode::IF: cout << "Type IF" << endl; break; case ASTNode::INSTANCE_OF: cout << "Type INSTANCE_OF" << endl; break; case ASTNode::CASTABLE_AS: cout << "Type CASTABLE_AS" << endl; break; case ASTNode::CAST_AS: cout << "Type CAST_AS" << endl; break; case ASTNode::TREAT_AS: cout << "Type TREAT_AS" << endl; break; case ASTNode::OPERATOR: { cout << "Type OPERATOR" << endl; XQOperator *op = reinterpret_cast<XQOperator *>(node); VectorOfASTNodes const &args(op->getArguments()); for (VectorOfASTNodes::const_iterator it = args.begin(); it != args.end(); ++it) inspect(*it, scope, dtd); break; } case ASTNode::CONTEXT_ITEM: cout << "Type CONTEXT_ITEM" << endl; break; case ASTNode::DOM_CONSTRUCTOR: cout << "Type DOM_CONSTRUCTOR" << endl; break; case ASTNode::QUANTIFIED: cout << "Type QUANTIFIED" << endl; break; case ASTNode::TYPESWITCH: cout << "Type TYPESWITCH" << endl; break; case ASTNode::VALIDATE: cout << "Type VALIDATE" << endl; break; case ASTNode::FUNCTION_CALL: cout << "Type FUNCTION_CALL" << endl; break; case ASTNode::USER_FUNCTION: cout << "Type USER_FUNCTION" << endl; break; case ASTNode::ORDERING_CHANGE: cout << "Type ORDERING_CHANGE" << endl; break; case ASTNode::XPATH1_CONVERT: { cout << "Type XPATH1_CONVERT" << endl; XPath1CompatConvertFunctionArg *conv = reinterpret_cast<XPath1CompatConvertFunctionArg *>(node); inspect(conv->getExpression(), scope, dtd); break; } case ASTNode::PROMOTE_UNTYPED: cout << "Type PROMOTE_UNTYPED" << endl; break; case ASTNode::PROMOTE_NUMERIC: cout << "Type PROMOTE_NUMERIC" << endl; break; case ASTNode::PROMOTE_ANY_URI: cout << "Type PROMOTE_ANY_URI" << endl; break; case ASTNode::DOCUMENT_ORDER: { cout << "Type DOCUMENT_ORDER" << endl; XQDocumentOrder *docOrder = reinterpret_cast<XQDocumentOrder*>(node); inspect(docOrder->getExpression(), scope, dtd); break; } case ASTNode::PREDICATE: { cout << "Type PREDICATE" << endl; XQPredicate *predicate = reinterpret_cast<XQPredicate*>(node); std::tr1::shared_ptr<QueryScope> stepScope(new QueryScope(scope)); inspect(predicate->getExpression(), stepScope, dtd); inspect(predicate->getPredicate(), stepScope, dtd); break; } case ASTNode::ATOMIZE: { cout << "Type ATOMIZE" << endl; XQAtomize *atomize = reinterpret_cast<XQAtomize*>(node); inspect(atomize->getExpression(), scope, dtd); break; } case ASTNode::EBV: cout << "Type EBV" << endl; break; case ASTNode::FTCONTAINS: cout << "Type FTCONTAINS" << endl; break; case ASTNode::UDELETE: cout << "Type UDELETE" << endl; break; case ASTNode::URENAME: cout << "Type URENAME" << endl; break; case ASTNode::UREPLACE: cout << "Type UREPLACE" << endl; break; case ASTNode::UREPLACE_VALUE_OF: cout << "Type UREPLACE_VALUE_OF" << endl; break; case ASTNode::UTRANSFORM: cout << "Type UTRANSFORM" << endl; break; case ASTNode::UINSERT_AS_FIRST: cout << "Type UINSERT_AS_FIRST" << endl; break; case ASTNode::UINSERT_AS_LAST: cout << "Type UINSERT_AS_LAST" << endl; break; case ASTNode::UINSERT_INTO: cout << "Type UINSERT_INTO" << endl; break; case ASTNode::UINSERT_AFTER: cout << "Type UINSERT_AFTER" << endl; break; case ASTNode::UINSERT_BEFORE: cout << "Type UINSERT_BEFORE" << endl; break; case ASTNode::UAPPLY_UPDATES: cout << "Type UAPPLY_UPDATES" << endl; break; case ASTNode::NAME_EXPRESSION: cout << "Type NAME_EXPRESSION" << endl; break; case ASTNode::CONTENT_SEQUENCE: cout << "Type CONTENT_SEQUENCE" << endl; break; case ASTNode::DIRECT_NAME: cout << "Type DIRECT_NAME" << endl; break; case ASTNode::RETURN: cout << "Type RETURN" << endl; break; case ASTNode::NAMESPACE_BINDING: cout << "Type NAMESPACE_BINDING" << endl; break; case ASTNode::FUNCTION_CONVERSION: cout << "Type FUNCTION_CONVERSION" << endl; break; case ASTNode::SIMPLE_CONTENT: cout << "Type SIMPLE_CONTENT" << endl; break; case ASTNode::ANALYZE_STRING: cout << "Type ANALYZE_STRING" << endl; break; case ASTNode::CALL_TEMPLATE: cout << "Type CALL_TEMPLATE" << endl; break; case ASTNode::APPLY_TEMPLATES: cout << "Type APPLY_TEMPLATES" << endl; break; case ASTNode::INLINE_FUNCTION: cout << "Type INLINE_FUNCTION" << endl; break; case ASTNode::FUNCTION_REF: cout << "Type FUNCTION_REF" << endl; break; case ASTNode::FUNCTION_DEREF: cout << "Type FUNCTION_DEREF" << endl; break; case ASTNode::COPY_OF: cout << "Type COPY_OF" << endl; break; case ASTNode::COPY: cout << "Type COPY" << endl; break; case ASTNode::MAP: cout << "Type MAP" << endl; break; case ASTNode::DEBUG_HOOK: cout << "Type DEBUG_HOOK" << endl; break; } }
ASTNode *FunctionRefImpl::createInstance(const XMLCh *uri, const XMLCh *name, unsigned int numArgs, StaticContext *context, const LocationInfo *location, FunctionSignature *&signature) { XPath2MemoryManager *mm = context->getMemoryManager(); VectorOfASTNodes newArgs = VectorOfASTNodes(XQillaAllocator<ASTNode*>(mm)); for(unsigned int i = 0; i < numArgs; ++i) { newArgs.push_back(0); // Dummy argument } ASTNode *result = context->lookUpFunction(uri, name, newArgs, location); if(!result) return 0; switch(result->getType()) { case ASTNode::FUNCTION: case ASTNode::USER_FUNCTION: { XQFunction *function = (XQFunction*)result; function->parseSignature(context); signature = new (mm) FunctionSignature(function->getSignature(), mm); if(signature->argSpecs) { // Fill in the arguments with XQVariable objects ArgumentSpecs::const_iterator argsIt = signature->argSpecs->begin(); VectorOfASTNodes &args = const_cast<VectorOfASTNodes&>(function->getArguments()); for(VectorOfASTNodes::iterator i = args.begin(); i != args.end(); ++i, ++argsIt) { (*i) = new (mm) XQVariable((*argsIt)->getURI(), (*argsIt)->getName(), mm); (*i)->setLocationInfo(location); } } break; } case ASTNode::CAST_AS: { XQCastAs *cast = (XQCastAs*)result; // Fill in the argument with an XQVariable object XQVariable *var = new (mm) XQVariable(0, constructorArgName, mm); var->setLocationInfo(location); cast->setExpression(var); // Create a signature for the constructor function SequenceType *argType = new (mm) SequenceType(SchemaSymbols::fgURI_SCHEMAFORSCHEMA, AnyAtomicType::fgDT_ANYATOMICTYPE, SequenceType::QUESTION_MARK, mm); argType->setLocationInfo(location); ArgumentSpec *arg = new (mm) ArgumentSpec(constructorArgName, argType, mm); arg->setLocationInfo(location); ArgumentSpecs *args = new (mm) ArgumentSpecs(XQillaAllocator<ArgumentSpec*>(mm)); args->push_back(arg); signature = new (mm) FunctionSignature(args, cast->getSequenceType(), mm); signature->staticResolution(context); break; } default: assert(false); break; } return result; }