예제 #1
0
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;
    }
}
예제 #2
0
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;
}