← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba

 

Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.

Commit message:
Allow multiple default function namespaces

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/153930

Allow multiple default function namespaces
-- 
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/153930
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-03-16 20:55:24 +0000
+++ ChangeLog	2013-03-18 20:46:31 +0000
@@ -15,7 +15,12 @@
     for streamable strings and base64Binary.
   * Added millis-to-dateTime() function in datetime module.
   * fn:trace outputs "empty-sequence()" if the input is the empty-sequence.
+<<<<<<< TREE
   * Added xqxq:variable-value function.
+=======
+  * Addex xqxq:variable-value function.
+  * Allow multiple default function namespaces.
+>>>>>>> MERGE-SOURCE
   * Added canonicalize function to modules/xml.
   * Added support for xs:dateTimeStamp type from XMLSchema 1.1, bug #924754.
 

=== modified file 'src/api/staticcontextimpl.cpp'
--- src/api/staticcontextimpl.cpp	2013-02-07 17:24:36 +0000
+++ src/api/staticcontextimpl.cpp	2013-03-18 20:46:31 +0000
@@ -316,7 +316,7 @@
 
 ********************************************************************************/
 String
-StaticContextImpl::getDefaultFunctionNamespace( ) const
+StaticContextImpl::getDefaultFunctionNamespace() const
 {
   try
   {

=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp	2013-03-08 00:09:46 +0000
+++ src/compiler/translator/translator.cpp	2013-03-18 20:46:31 +0000
@@ -1031,6 +1031,11 @@
   Convert a lexical qname identifying a function to an expanded qname item.
   If the lexical qname does not have a prefix, the default function namespace
   (if any) will be used to build the expanded qname item.
+
+  Raise error is the prefix is non-empty and there is no ns associated with it.
+
+  This method is used during the processing of function declarations (when the
+  function object is not supposed to exist already).
 ********************************************************************************/
 void expand_function_qname(
     store::Item_t& qnameItem,
@@ -1297,7 +1302,7 @@
 ********************************************************************************/
 void bind_fn(
     function_t& f,
-    ulong nargs,
+    csize nargs,
     const QueryLoc& loc)
 {
   theSctx->bind_fn(f, nargs, loc);
@@ -1313,14 +1318,16 @@
 
 /*******************************************************************************
   Lookup in the sctx the function object for a function with a given prefix
-  local name and arity. Return NULL if such a function is not found
+  local name and arity. Raise error if the prefix is non-empty and does not have
+  an associated namespace. Return NULL if such a function is not found.
 ********************************************************************************/
-function* lookup_fn(const QName* qname, ulong arity, const QueryLoc& loc)
+function* lookup_fn(const QName* qname, csize arity, const QueryLoc& loc)
 {
-  store::Item_t qnameItem;
-  expand_function_qname(qnameItem, qname, loc);
-
-  return theSctx->lookup_fn(qnameItem, arity);
+  return theSctx->lookup_fn(qname->get_namespace(),
+                            qname->get_prefix(),
+                            qname->get_localname(),
+                            arity,
+                            loc);
 }
 
 
@@ -4140,10 +4147,10 @@
 
   //bool recognised = false;
 
-  store::Item_t lExpandedQName;
-  expand_function_qname(lExpandedQName, v.get_qname(), loc);
+  store::Item_t expandedQName;
+  expand_function_qname(expandedQName, v.get_qname(), loc);
 
-  zstring annotNS = lExpandedQName->getNamespace();
+  zstring annotNS = expandedQName->getNamespace();
 
   if (annotNS == static_context::W3C_XML_NS ||
       annotNS == XML_SCHEMA_NS ||
@@ -4152,10 +4159,10 @@
       annotNS == XQUERY_MATH_FN_NS ||
       annotNS == ZORBA_ANNOTATIONS_NS)
   {
-    if (AnnotationInternal::lookup(lExpandedQName) == AnnotationInternal::zann_end)
+    if (AnnotationInternal::lookup(expandedQName) == AnnotationInternal::zann_end)
     {
       RAISE_ERROR(err::XQST0045, loc,
-      ERROR_PARAMS(lExpandedQName->getLocalName(), ZED(ANNOTATION), annotNS));
+      ERROR_PARAMS(expandedQName->getLocalName(), ZED(ANNOTATION), annotNS));
     }
 
     //recognised = true;
@@ -4177,7 +4184,7 @@
   }
 
   //if (recognised)
-    theAnnotations->push_back(lExpandedQName, lLiterals);
+    theAnnotations->push_back(expandedQName, lLiterals);
 }
 
 
@@ -10738,20 +10745,6 @@
 
   TypeManager* tm = CTX_TM;
 
-  // Expand the function qname
-  rchandle<QName> qname = v.get_fname();
-
-  store::Item_t qnameItem;
-  expand_function_qname(qnameItem, qname, loc);
-
-  const zstring& fn_ns = qnameItem->getNamespace();
-
-  if (static_context::is_reserved_module(fn_ns))
-  {
-    RAISE_ERROR(zerr::ZXQP0016_RESERVED_MODULE_TARGET_NAMESPACE, loc,
-    ERROR_PARAMS(fn_ns));
-  }
-
   // Collect the arguments of this function in reverse order
   std::vector<expr*> arguments;
 
@@ -10767,17 +10760,82 @@
 
   csize numArgs = arguments.size();
 
+  // Lookup the function
+  store::Item_t qnameItem;
+  const QName* qname = v.get_fname();
+
   function* f = lookup_fn(qname, numArgs, loc);
 
+  zstring fn_ns;
+
+  if (f != NULL)
+  {
+    qnameItem = f->getName();
+    fn_ns = qnameItem->getNamespace();
+
+    if (static_context::is_reserved_module(fn_ns))
+    {
+      RAISE_ERROR(zerr::ZXQP0016_RESERVED_MODULE_TARGET_NAMESPACE, loc,
+                  ERROR_PARAMS(fn_ns));
+    }
+  }
+  else
+  {
+    // Check if this is a call to a type constructor function
+    const zstring& local = qname->get_localname();
+    const zstring& prefix = qname->get_prefix();
+
+    if (prefix.empty())
+    {
+      GENV_ITEMFACTORY->
+      createQName(qnameItem, XML_SCHEMA_NS, "", local);
+    }
+    else
+    {
+      expand_function_qname(qnameItem, qname, loc);
+    }
+
+    xqtref_t type = CTX_TM->create_named_type(qnameItem,
+                                              TypeConstants::QUANT_QUESTION,
+                                              loc);
+
+    if (type != NULL)
+    {
+      if (numArgs != 1 ||
+          TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.NOTATION_TYPE_QUESTION, loc) ||
+          TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_QUESTION, loc))
+      {
+        RAISE_ERROR(err::XPST0017, loc,
+        ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
+      }
+
+      push_nodestack(create_cast_expr(loc, arguments[0], type, true, true));
+
+      return;
+    }
+
+    if (theHaveModuleImportCycle)
+    {
+      std::map<zstring, zstring>::const_iterator ite = theModulesStack.begin();
+      std::map<zstring, zstring>::const_iterator end = theModulesStack.end();
+
+      --end;
+      assert((*end).second == theModuleNamespace);
+
+      for (; ite != end; ++ite)
+      {
+        if ((*ite).second == fn_ns)
+          RAISE_ERROR(err::XQST0093, loc, ERROR_PARAMS(theModuleNamespace));
+      }
+    }
+    
+    RAISE_ERROR(err::XPST0017, loc,
+    ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
+  }
+
   if (fn_ns == static_context::W3C_FN_NS)
   {
     // Some special processing is required for certain "fn" functions
-    if (f == NULL)
-    {
-      RAISE_ERROR(err::XPST0017, loc,
-      ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
-    }
-
     switch (f->getKind())
     {
       case FunctionConsts::FN_HEAD_1:
@@ -11062,48 +11120,7 @@
 
   numArgs = arguments.size();  // recompute size
 
-  // Check if this is a call to a type constructor function
-  xqtref_t type = CTX_TM->create_named_type(qnameItem,
-                                            TypeConstants::QUANT_QUESTION,
-                                            loc);
-
-  if (type != NULL)
-  {
-    if (numArgs != 1 ||
-        TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.NOTATION_TYPE_QUESTION, loc) ||
-        TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_QUESTION, loc))
-    {
-      RAISE_ERROR(err::XPST0017, loc,
-      ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
-    }
-
-    push_nodestack(create_cast_expr(loc, arguments[0], type, true, true));
-  }
-
-  // It is not a builtin constructor function
-  else
-  {
-    if (f == NULL)
-    {
-      if (theHaveModuleImportCycle)
-      {
-        std::map<zstring, zstring>::const_iterator ite = theModulesStack.begin();
-        std::map<zstring, zstring>::const_iterator end = theModulesStack.end();
-
-        --end;
-        assert((*end).second == theModuleNamespace);
-
-        for (; ite != end; ++ite)
-        {
-          if ((*ite).second == fn_ns)
-            RAISE_ERROR(err::XQST0093, loc, ERROR_PARAMS(theModuleNamespace));
-        }
-      }
-
-      RAISE_ERROR(err::XPST0017, loc,
-      ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
-    }
-
+  {
     // If this is a udf that is invoked from another udf, mark that other udf
     // as a non-leaf function.
     if (f->isUdf())

=== modified file 'src/context/root_static_context.cpp'
--- src/context/root_static_context.cpp	2013-02-07 17:24:36 +0000
+++ src/context/root_static_context.cpp	2013-03-18 20:46:31 +0000
@@ -158,6 +158,7 @@
   set_default_elem_type_ns(zstring(), true, loc);   
 
   set_default_function_ns(W3C_FN_NS, true, loc);
+  set_default_function_ns(JSONIQ_FN_NS, false, loc);
 
   add_collation(ZORBA_DEF_COLLATION_NS, QueryLoc::null);
   add_collation(W3C_CODEPT_COLLATION_NS, QueryLoc::null);

=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp	2013-02-26 04:12:43 +0000
+++ src/context/static_context.cpp	2013-03-18 20:46:31 +0000
@@ -677,7 +677,6 @@
   theExternalModulesMap(NULL),
   theNamespaceBindings(NULL),
   theHaveDefaultElementNamespace(false),
-  theHaveDefaultFunctionNamespace(false),
   theContextItemType(NULL),
   theVariablesMap(NULL),
   theImportedPrivateVariablesMap(NULL),
@@ -724,7 +723,6 @@
   theExternalModulesMap(NULL),
   theNamespaceBindings(NULL),
   theHaveDefaultElementNamespace(false),
-  theHaveDefaultFunctionNamespace(false),
   theContextItemType(NULL),
   theVariablesMap(NULL),
   theImportedPrivateVariablesMap(NULL),
@@ -776,7 +774,6 @@
   theExternalModulesMap(NULL),
   theNamespaceBindings(NULL),
   theHaveDefaultElementNamespace(false),
-  theHaveDefaultFunctionNamespace(false),
   theContextItemType(NULL),
   theVariablesMap(NULL),
   theImportedPrivateVariablesMap(NULL),
@@ -1086,8 +1083,7 @@
   ar & theNamespaceBindings;
   ar & theDefaultElementNamespace;
   ar & theHaveDefaultElementNamespace;
-  ar & theDefaultFunctionNamespace;
-  ar & theHaveDefaultFunctionNamespace;
+  ar & theDefaultFunctionNamespaces;
 
   ar & theContextItemType;
 
@@ -2039,9 +2035,9 @@
 ********************************************************************************/
 const zstring& static_context::default_function_ns() const
 {
-  if (theHaveDefaultFunctionNamespace || theParent == NULL)
+  if (!theDefaultFunctionNamespaces.empty() || theParent == NULL)
   {
-    return theDefaultFunctionNamespace;
+    return theDefaultFunctionNamespaces[0];
   }
   else
   {
@@ -2058,10 +2054,9 @@
    bool raiseError,
    const QueryLoc& loc)
 {
-  if (!theHaveDefaultFunctionNamespace)
+  if (theDefaultFunctionNamespaces.empty())
   {
-    theDefaultFunctionNamespace = ns;
-    theHaveDefaultFunctionNamespace = true;
+    theDefaultFunctionNamespaces.push_back(ns);
   }
   else if (raiseError)
   {
@@ -2069,7 +2064,7 @@
   }
   else
   {
-    theDefaultFunctionNamespace = ns;
+    theDefaultFunctionNamespaces.insert(theDefaultFunctionNamespaces.begin(), ns);
   }
 }
 
@@ -2429,7 +2424,7 @@
 ********************************************************************************/
 void static_context::bind_fn(
     function_t& f,
-    ulong arity,
+    csize arity,
     const QueryLoc& loc)
 {
   store::Item* qname = f->getName();
@@ -2441,7 +2436,7 @@
 
   if (theFunctionMap == NULL)
   {
-    ulong size = (is_global_root_sctx() ? 500 : 32);
+    csize size = (is_global_root_sctx() ? 500 : 32);
     theFunctionMap = new FunctionMap(HashMapItemPointerCmp(0, NULL), size, false);
   }
 
@@ -2503,7 +2498,7 @@
 ********************************************************************************/
 void static_context::unbind_fn(
     const store::Item* qname,
-    ulong arity)
+    csize arity)
 {
   ZORBA_ASSERT(!is_global_root_sctx());
 
@@ -2563,6 +2558,59 @@
 }
 
 
+/*******************************************************************************
+  Search in the sctx, starting from "this" and moving upwards, for the function
+  object for a function with a given prefix local name and arity. Raise error if
+  the prefix is non-empty and does not have an associated namespace. Return NULL
+  if such a function is not found.
+********************************************************************************/
+function* static_context::lookup_fn(
+    const zstring& ns,
+    const zstring& pre,
+    const zstring& local,
+    csize arity,
+    const QueryLoc& loc)
+{
+  store::Item_t qnameItem;
+  std::vector<zstring>::const_iterator ite;
+  std::vector<zstring>::const_iterator end;
+  function* f = NULL;
+
+  if (!ns.empty())
+  {
+    ITEM_FACTORY->createQName(qnameItem, ns, "", local);
+
+    f = lookup_fn(qnameItem, arity, true);
+  }
+  else if (!pre.empty())
+  {
+    expand_qname(qnameItem, "", pre, local, loc);
+    
+    f = lookup_fn(qnameItem, arity, true);
+  }
+  else
+  {
+    static_context* sctx = this;
+
+    while (f == NULL && sctx != NULL)
+    {
+      ite = sctx->theDefaultFunctionNamespaces.begin();
+      end = sctx->theDefaultFunctionNamespaces.end();
+
+      for (; f == NULL && ite != end; ++ite)
+      {
+        ITEM_FACTORY->createQName(qnameItem, *ite, "", local);
+        f = lookup_fn(qnameItem, arity, true);
+      }
+
+      sctx = sctx->theParent;
+    }
+  }
+
+  return f;
+}
+
+
 /***************************************************************************//**
   Search the static-context tree, starting from "this" and moving upwards,
   looking for the 1st sctx obj that contains a binding for a function with
@@ -2572,7 +2620,7 @@
 ********************************************************************************/
 function* static_context::lookup_fn(
     const store::Item* qname,
-    ulong arity,
+    csize arity,
     bool skipDisabled)
 {
   FunctionInfo fi;
@@ -2627,7 +2675,7 @@
 ********************************************************************************/
 function* static_context::lookup_local_fn(
     const store::Item* qname,
-    ulong arity,
+    csize arity,
     bool skipDisabled)
 {
   FunctionInfo fi;

=== modified file 'src/context/static_context.h'
--- src/context/static_context.h	2013-02-26 04:12:43 +0000
+++ src/context/static_context.h	2013-03-18 20:46:31 +0000
@@ -352,9 +352,9 @@
   ----------------------------
   The namespace URI to be used for element and type qnames whose prefix is empty.
 
-  theDefaultFunctionNamespace :
-  -----------------------------
-  The namespace URI to be used for function qnames whose prefix is empty.
+  theDefaultFunctionNamespaces :
+  ------------------------------
+  The namespace URIs to be used for function qnames whose prefix is empty.
 
   theContextItemType :
   --------------------
@@ -598,8 +598,7 @@
   zstring                                 theDefaultElementNamespace;
   bool                                    theHaveDefaultElementNamespace;
 
-  zstring                                 theDefaultFunctionNamespace;
-  bool                                    theHaveDefaultFunctionNamespace;
+  std::vector<zstring>                    theDefaultFunctionNamespaces;
 
   xqtref_t                                theContextItemType;
 
@@ -893,18 +892,25 @@
   //
   // Functions
   //
-  void bind_fn(function_t& f, ulong arity, const QueryLoc& loc);
-
-  void unbind_fn(const store::Item* qname, ulong arity);
+  void bind_fn(function_t& f, csize arity, const QueryLoc& loc);
+
+  void unbind_fn(const store::Item* qname, csize arity);
+
+  function* lookup_fn(
+      const zstring& ns,
+      const zstring& pre,
+      const zstring& local,
+      csize arity,
+      const QueryLoc& loc);
 
   function* lookup_fn(
       const store::Item* qname,
-      ulong arity,
+      csize arity,
       bool skipDisabled = true);
 
   function* lookup_local_fn(
       const store::Item* qname,
-      ulong arity,
+      csize arity,
       bool skipDisabled = true);
 
   void get_functions(std::vector<function*>& functions) const;

=== modified file 'test/rbkt/Queries/zorba/jsoniq/dataguide.xq'
--- test/rbkt/Queries/zorba/jsoniq/dataguide.xq	2013-03-11 10:00:36 +0000
+++ test/rbkt/Queries/zorba/jsoniq/dataguide.xq	2013-03-18 20:46:31 +0000
@@ -13,25 +13,25 @@
          case array() return { append json . into $arr; }
          default return { append json . into $val; });
 
-   if (jn:size($val) eq 0)
-   then ()
-   else ["_VAL", jn:members($val)],
-
-   if (jn:size($obj) eq 0)
-   then ()
-   else ["_OBJ", local:collapse-objects(jn:members($obj))],
-
-   if (jn:size($arr) eq 0)
-   then ()
-   else  ["_ARR", local:collapse-general(jn:members($arr) ! jn:members(.)) ]
+   if (size($val) eq 0)
+   then ()
+   else ["_VAL", members($val)],
+
+   if (size($obj) eq 0)
+   then ()
+   else ["_OBJ", local:collapse-objects(members($obj))],
+
+   if (size($arr) eq 0)
+   then ()
+   else  ["_ARR", local:collapse-general(members($arr) ! members(.)) ]
 };
 
 
 declare %an:sequential function local:collapse-objects($x as object()*)
 {
-  jn:object(for $y in distinct-values($x ! (jn:keys(.)))
-            let $z := $x($y)
-            return {$y : local:collapse-general($z)})
+  object(for $y in distinct-values($x ! (keys(.)))
+         let $z := $x($y)
+         return {$y : local:collapse-general($z)})
 };
 
 


Follow ups