zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #13318
[Merge] lp:~zorba-coders/zorba/bug-900688 into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/bug-900688 into lp:zorba.
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-900688/+merge/119998
Allow prolog variables to be referenced before they are declared (XQuery 3.0 feature) (fixes bug #900688)
--
https://code.launchpad.net/~zorba-coders/zorba/bug-900688/+merge/119998
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/parser/xquery_parser.y'
--- src/compiler/parser/xquery_parser.y 2012-08-14 11:13:50 +0000
+++ src/compiler/parser/xquery_parser.y 2012-08-16 18:30:28 +0000
@@ -1665,45 +1665,42 @@
{
std::auto_ptr<VarNameAndType> nt(dynamic_cast<VarNameAndType *>($2));
- $$ = new VarDecl(LOC(@$),
- nt->theName,
- nt->theType,
- $4,
- nt->get_annotations(),
- true, // global
- false); // not external
+ $$ = new GlobalVarDecl(LOC(@$),
+ nt->theName,
+ nt->theType,
+ $4,
+ nt->get_annotations(),
+ false); // not external
- dynamic_cast<VarDecl*>($$)->setComment(SYMTAB($1));
+ static_cast<GlobalVarDecl*>($$)->setComment(SYMTAB($1));
}
|
DECLARE VarNameAndType EXTERNAL
{
std::auto_ptr<VarNameAndType> nt(dynamic_cast<VarNameAndType *>($2));
- $$ = new VarDecl(LOC(@$),
- nt->theName,
- nt->theType,
- NULL, // no init expr
- nt->get_annotations(),
- true, // global
- true); // external
+ $$ = new GlobalVarDecl(LOC(@$),
+ nt->theName,
+ nt->theType,
+ NULL, // no init expr
+ nt->get_annotations(),
+ true); // external
- dynamic_cast<VarDecl*>($$)->setComment(SYMTAB($1));
+ static_cast<GlobalVarDecl*>($$)->setComment(SYMTAB($1));
}
|
DECLARE VarNameAndType EXTERNAL GETS ExprSingle
{
std::auto_ptr<VarNameAndType> nt(dynamic_cast<VarNameAndType *>($2));
- $$ = new VarDecl(LOC(@$),
- nt->theName,
- nt->theType,
- $5, // init expr
- nt->get_annotations(),
- true, // global
- true); // external
+ $$ = new GlobalVarDecl(LOC(@$),
+ nt->theName,
+ nt->theType,
+ $5, // init expr
+ nt->get_annotations(),
+ true); // external
- dynamic_cast<VarDecl*>($$)->setComment(SYMTAB($1));
+ static_cast<GlobalVarDecl*>($$)->setComment(SYMTAB($1));
}
;
@@ -2271,7 +2268,8 @@
|
AnnotationList VARIABLE BlockVarDecl
{
- VarDeclStmt* vdecl = new VarDeclStmt(LOC(@$), static_cast<AnnotationListParsenode*>($1));
+ VarDeclStmt* vdecl = new VarDeclStmt(LOC(@$),
+ static_cast<AnnotationListParsenode*>($1));
vdecl->add($3);
$$ = vdecl;
}
@@ -2281,51 +2279,38 @@
BlockVarDecl :
DOLLAR QNAME
{
- VarDecl* vd = new VarDecl(LOC(@$),
- static_cast<QName*>($2),
- NULL, // no type
- NULL, // no init expr
- NULL, // no annotations
- false, // not global
- false);// not external
- vd->set_global(false);
+ LocalVarDecl* vd = new LocalVarDecl(LOC(@$),
+ static_cast<QName*>($2),
+ NULL, // no type
+ NULL, // no init expr
+ NULL); // no annotations
$$ = vd;
}
| DOLLAR QNAME TypeDeclaration
{
- VarDecl* vd = new VarDecl(LOC(@$),
- static_cast<QName*>($2),
- dynamic_cast<SequenceType*>($3), // type
- NULL, // no init expr
- NULL, // no annotations
- false, // not global
- false);// not external
-
- vd->set_global(false);
+ LocalVarDecl* vd = new LocalVarDecl(LOC(@$),
+ static_cast<QName*>($2),
+ dynamic_cast<SequenceType*>($3), // type
+ NULL, // no init expr
+ NULL); // no annotations
$$ = vd;
}
| DOLLAR QNAME GETS ExprSingle
{
- VarDecl* vd = new VarDecl(LOC(@$),
- static_cast<QName*>($2),
- NULL, // no type
- $4, // init expr
- NULL, // no annotations
- false, // not global
- false);// not external
- vd->set_global(false);
+ LocalVarDecl* vd = new LocalVarDecl(LOC(@$),
+ static_cast<QName*>($2),
+ NULL, // no type
+ $4, // init expr
+ NULL); // no annotations
$$ = vd;
}
| DOLLAR QNAME TypeDeclaration GETS ExprSingle
{
- VarDecl* vd = new VarDecl(LOC(@$),
- static_cast<QName*>($2),
- dynamic_cast<SequenceType*>($3), // type
- $5, // init expr
- NULL, // no annotations
- false, // not global
- false);// not external
- vd->set_global(false);
+ LocalVarDecl* vd = new LocalVarDecl(LOC(@$),
+ static_cast<QName*>($2),
+ dynamic_cast<SequenceType*>($3), // type
+ $5, // init expr
+ NULL); // no annotations
$$ = vd;
}
;
=== modified file 'src/compiler/parsetree/parsenode_print_xml_visitor.cpp'
--- src/compiler/parsetree/parsenode_print_xml_visitor.cpp 2012-08-14 11:13:50 +0000
+++ src/compiler/parsetree/parsenode_print_xml_visitor.cpp 2012-08-16 18:30:28 +0000
@@ -370,7 +370,7 @@
NO_END_TAG (ValueComp)
-void *begin_visit(const VarDecl &n)
+void* begin_visit(const GlobalVarDecl &n)
{
INDENT;
@@ -384,6 +384,20 @@
}
+void* begin_visit(const LocalVarDecl &n)
+{
+ INDENT;
+
+ os << "<LocalVarDecl pos='" << n.get_location() << "' var='"
+ << n.get_var_name()->get_qname() << "' ptr='" << &n << "'";
+
+ os << ">";
+
+ INDENT_INC; NL;
+ return no_state;
+}
+
+
void *begin_visit(const VarGetsDecl &n)
{
INDENT;
@@ -808,7 +822,8 @@
BEGIN_END_TAG (IndexKeySpec)
BEGIN_END_TAG (IndexKeyList)
BEGIN_END_TAG (IntegrityConstraintDecl)
-END_TAG (VarDecl)
+END_TAG (GlobalVarDecl)
+END_TAG (LocalVarDecl)
END_TAG (VarGetsDecl)
BEGIN_END_TAG (VarGetsDeclList)
END_TAG (VarInDecl)
=== modified file 'src/compiler/parsetree/parsenode_print_xqdoc_visitor.cpp'
--- src/compiler/parsetree/parsenode_print_xqdoc_visitor.cpp 2012-08-14 11:13:50 +0000
+++ src/compiler/parsetree/parsenode_print_xqdoc_visitor.cpp 2012-08-16 18:30:28 +0000
@@ -900,10 +900,8 @@
map<zstring, zstring>::iterator ite = theNamespaceMap.find(aPrefix);
if (ite == theNamespaceMap.end())
{
- throw ZORBA_EXCEPTION(
- zerr::ZXQD0001_PREFIX_NOT_DECLARED,
- ERROR_PARAMS( aPrefix, aLocalName, aLocation )
- );
+ throw ZORBA_EXCEPTION(zerr::ZXQD0001_PREFIX_NOT_DECLARED,
+ ERROR_PARAMS(aPrefix, aLocalName, aLocation ));
}
zstring lNS = ite->second;
@@ -936,13 +934,10 @@
}
-XQDOC_NO_BEGIN_TAG (VarDecl)
+XQDOC_NO_BEGIN_TAG (GlobalVarDecl)
-void end_visit(const VarDecl& n, void*)
+void end_visit(const GlobalVarDecl& n, void*)
{
- if (!n.is_global())
- return;
-
store::Item_t lVariableQName, lUriQName;
store::Item_t lVariableElem, lUriElem, lUriText;
@@ -1276,6 +1271,7 @@
XQDOC_NO_BEGIN_END_TAG (ValidateExpr)
XQDOC_NO_BEGIN_END_TAG (ValueComp)
XQDOC_NO_BEGIN_END_TAG (VarBinding)
+XQDOC_NO_BEGIN_END_TAG( LocalVarDecl )
XQDOC_NO_BEGIN_END_TAG (VarGetsDecl)
XQDOC_NO_BEGIN_END_TAG (VarGetsDeclList)
XQDOC_NO_BEGIN_END_TAG (VarInDecl)
=== modified file 'src/compiler/parsetree/parsenode_print_xquery_visitor.cpp'
--- src/compiler/parsetree/parsenode_print_xquery_visitor.cpp 2012-08-14 11:13:50 +0000
+++ src/compiler/parsetree/parsenode_print_xquery_visitor.cpp 2012-08-16 18:30:28 +0000
@@ -1044,23 +1044,49 @@
DEFAULT_VISIT (IndexKeyList)
DEFAULT_VISIT (IntegrityConstraintDecl)
- void* begin_visit(const VarDecl& n)
+ void* begin_visit(const GlobalVarDecl& n)
{
os << "declare variable $" << n.get_var_name()->get_qname();
- if(n.get_var_type())
+
+ if (n.get_var_type())
{
n.get_var_type()->accept(*this);
}
- if(n.is_extern())
+
+ if (n.is_extern())
{
os << "external";
- } else if(n.get_binding_expr()) {
- os << ":=";
- n.get_binding_expr()->accept(*this);
- }
- return 0;
- }
- DEFAULT_END_VISIT (VarDecl)
+ }
+
+ if (n.get_binding_expr())
+ {
+ os << ":=";
+ n.get_binding_expr()->accept(*this);
+ }
+ return 0;
+ }
+
+ DEFAULT_END_VISIT (GlobalVarDecl)
+
+ void* begin_visit(const LocalVarDecl& n)
+ {
+ os << "variable $" << n.get_var_name()->get_qname();
+
+ if (n.get_var_type())
+ {
+ n.get_var_type()->accept(*this);
+ }
+
+ if (n.get_binding_expr())
+ {
+ os << ":=";
+ n.get_binding_expr()->accept(*this);
+ }
+ return 0;
+ }
+
+ DEFAULT_END_VISIT (LocalVarDecl)
+
void* begin_visit(const VarGetsDecl& n)
{
=== modified file 'src/compiler/parsetree/parsenode_visitor.h'
--- src/compiler/parsetree/parsenode_visitor.h 2012-08-14 11:13:50 +0000
+++ src/compiler/parsetree/parsenode_visitor.h 2012-08-16 18:30:28 +0000
@@ -133,7 +133,8 @@
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( IndexKeySpec );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( IndexKeyList );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( IntegrityConstraintDecl );
- DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( VarDecl );
+ DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( GlobalVarDecl );
+ DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( LocalVarDecl );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( VarGetsDecl );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( VarGetsDeclList );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( VarInDecl );
=== modified file 'src/compiler/parsetree/parsenodes.cpp'
--- src/compiler/parsetree/parsenodes.cpp 2012-08-14 11:13:50 +0000
+++ src/compiler/parsetree/parsenodes.cpp 2012-08-16 18:30:28 +0000
@@ -720,36 +720,25 @@
VarValue ::= ExprSingle
VarDefaultValue ::= ExprSingle
-
-
- Local declarations:
- -------------------
-
- VarDeclStatement ::= ("local" Annotation*)? "variable"
- "$" VarName TypeDeclaration? (":=" ExprSingle)?
- ("," "$" VarName TypeDeclaration? (":=" ExprSingle)?)* ";"
********************************************************************************/
-VarDecl::VarDecl(
+GlobalVarDecl::GlobalVarDecl(
const QueryLoc& loc,
QName* varname,
SequenceType* type_decl,
exprnode* init_expr,
AnnotationListParsenode* annotations,
- bool global,
bool external)
:
VarDeclWithInit(loc, varname, type_decl, init_expr),
theIsExternal(external),
- theIsGlobal(global),
theAnnotations(annotations)
{
}
-void VarDecl::accept(parsenode_visitor& v) const
+void GlobalVarDecl::accept(parsenode_visitor& v) const
{
BEGIN_VISITOR();
- ACCEPT(theAnnotations);
ACCEPT(theType);
ACCEPT(theExpr);
END_VISITOR();
@@ -789,9 +778,9 @@
}
-ulong FunctionDecl::get_param_count() const
+csize FunctionDecl::get_param_count() const
{
- return theParams == NULL ? 0 : (ulong)theParams->size();
+ return theParams == NULL ? 0 : theParams->size();
}
@@ -1216,9 +1205,9 @@
{
VarDeclStmt* vdecl = static_cast<VarDeclStmt*>(statement);
- ulong numDecls = vdecl->size();
+ csize numDecls = vdecl->size();
- for (ulong i = 0; i < numDecls; ++i)
+ for (csize i = 0; i < numDecls; ++i)
{
theStatements.push_back(vdecl->getDecl(i));
}
@@ -1242,9 +1231,10 @@
{
}
+
void VarDeclStmt::add(parsenode* decl)
{
- VarDecl* varDecl = dynamic_cast<VarDecl*>(decl);
+ LocalVarDecl* varDecl = dynamic_cast<LocalVarDecl*>(decl);
if (varDecl != NULL)
{
varDecl->set_annotations(theAnnotations);
@@ -1253,6 +1243,7 @@
theDecls.push_back(decl);
}
+
void VarDeclStmt::accept(parsenode_visitor& v) const
{
assert(false);
@@ -1260,6 +1251,37 @@
/*******************************************************************************
+ Local declarations:
+ -------------------
+
+ VarDeclStatement ::= ("local" Annotation*)? "variable"
+ "$" VarName TypeDeclaration? (":=" ExprSingle)?
+ ("," "$" VarName TypeDeclaration? (":=" ExprSingle)?)* ";"
+********************************************************************************/
+LocalVarDecl::LocalVarDecl(
+ const QueryLoc& loc,
+ QName* varname,
+ SequenceType* type_decl,
+ exprnode* init_expr,
+ AnnotationListParsenode* annotations)
+ :
+ VarDeclWithInit(loc, varname, type_decl, init_expr),
+ theAnnotations(annotations)
+{
+}
+
+
+void LocalVarDecl::accept(parsenode_visitor& v) const
+{
+ BEGIN_VISITOR();
+ ACCEPT(theAnnotations);
+ ACCEPT(theType);
+ ACCEPT(theExpr);
+ END_VISITOR();
+}
+
+
+/*******************************************************************************
********************************************************************************/
void AssignExpr::accept(parsenode_visitor& v) const
=== modified file 'src/compiler/parsetree/parsenodes.h'
--- src/compiler/parsetree/parsenodes.h 2012-08-14 11:13:50 +0000
+++ src/compiler/parsetree/parsenodes.h 2012-08-16 18:30:28 +0000
@@ -950,30 +950,24 @@
/*******************************************************************************
********************************************************************************/
-class VarDecl : public VarDeclWithInit
+class GlobalVarDecl : public VarDeclWithInit
{
protected:
bool theIsExternal;
- bool theIsGlobal;
rchandle<AnnotationListParsenode> theAnnotations;
public:
- VarDecl(
+ GlobalVarDecl(
const QueryLoc& loc,
QName* varname,
SequenceType* type_decl,
exprnode* init_expr,
AnnotationListParsenode* annotations,
- bool global,
bool external);
bool is_extern() const { return theIsExternal; }
- bool is_global() const { return theIsGlobal; }
-
- void set_global(bool global) { theIsGlobal = global; }
-
void set_annotations(rchandle<AnnotationListParsenode> annotations)
{
theAnnotations = annotations;
@@ -1058,7 +1052,7 @@
rchandle<ParamList> get_paramlist() const { return theParams; }
- ulong get_param_count() const;
+ csize get_param_count() const;
rchandle<SequenceType> get_return_type() const { return theReturnType; }
@@ -1640,7 +1634,9 @@
/*******************************************************************************
-
+ VarDeclStatement ::= ("local" Annotation*)? "variable"
+ "$" VarName TypeDeclaration? (":=" ExprSingle)?
+ ("," "$" VarName TypeDeclaration? (":=" ExprSingle)?)* ";"
********************************************************************************/
class VarDeclStmt : public exprnode
{
@@ -1664,6 +1660,33 @@
/*******************************************************************************
********************************************************************************/
+class LocalVarDecl : public VarDeclWithInit
+{
+protected:
+ rchandle<AnnotationListParsenode> theAnnotations;
+
+public:
+ LocalVarDecl(
+ const QueryLoc& loc,
+ QName* varname,
+ SequenceType* type_decl,
+ exprnode* init_expr,
+ AnnotationListParsenode* annotations);
+
+ void set_annotations(rchandle<AnnotationListParsenode> annotations)
+ {
+ theAnnotations = annotations;
+ }
+
+ AnnotationListParsenode* get_annotations() const { return theAnnotations.getp(); }
+
+ void accept(parsenode_visitor&) const;
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
class AssignExpr : public exprnode
{
rchandle<QName> theName;
=== modified file 'src/compiler/translator/prolog_graph.cpp'
--- src/compiler/translator/prolog_graph.cpp 2012-08-14 11:13:50 +0000
+++ src/compiler/translator/prolog_graph.cpp 2012-08-16 18:30:28 +0000
@@ -24,6 +24,8 @@
#include "zorbatypes/zstring.h"
#include "diagnostics/xquery_exception.h"
+#include "diagnostics/dict.h"
+#include "diagnostics/util_macros.h"
namespace zorba
{
@@ -38,18 +40,36 @@
zstring varName;
if ( v )
varName = BUILD_STRING('$', v->getVarExpr()->get_name()->getStringValue());
- throw XQUERY_EXCEPTION(err::XQST0054, ERROR_PARAMS(varName), ERROR_LOC(loc));
-}
-
-
-/*******************************************************************************
- This method is part of the mechanism for detecting cycles in the dependency
+
+ RAISE_ERROR(err::XQST0054, loc, ERROR_PARAMS(varName));
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void PrologGraph::addEdge(const PrologGraphVertex& v1, const PrologGraphVertex& v2)
+{
+ if (v1.isVar() && v2.isVar() && v1.getVarExpr() == v2.getVarExpr())
+ {
+ zstring varName = '$' + v1.getVarExpr()->get_name()->getStringValue();
+
+ RAISE_ERROR(err::XPST0008, v2.getVarExpr()->get_loc(),
+ ERROR_PARAMS(varName, ZED(VariabledUndeclared)));
+ }
+
+ addEdge(theGraph, v1, v2);
+}
+
+
+/*******************************************************************************
+ This method is part of the mechanism for detecting cycles in the dependency
graph among prolog variables. The method does not actually detect the cycles
but re-orders the declarations of prolog vars (i.e., reorders theGlobalVars
list) so that if var v2 depends on var v1, then v1 appears before v2 in the
list (and as a result, v1 will be evaluated before v2 during runtime).
- Circular dependencies among prolog vars can appear only when udfs are invloved.
+ Circular dependencies among prolog vars can appear only when udfs are involved.
Here is an example:
declare variable $var := local:func1();
=== modified file 'src/compiler/translator/prolog_graph.h'
--- src/compiler/translator/prolog_graph.h 2012-08-14 11:13:50 +0000
+++ src/compiler/translator/prolog_graph.h 2012-08-16 18:30:28 +0000
@@ -77,6 +77,10 @@
Kind getKind() const { return theKind; }
+ bool isVar() const { return theKind == VAR; }
+
+ bool isUDF() const { return theKind == FUN; }
+
const function* getFunction() const
{
assert(theKind == FUN);
@@ -166,10 +170,7 @@
theFuncDecls.push_back(v);
}
- void addEdge(const PrologGraphVertex& v1, const PrologGraphVertex& v2)
- {
- addEdge(theGraph, v1, v2);
- }
+ void addEdge(const PrologGraphVertex& v1, const PrologGraphVertex& v2);
void reorder_globals(std::list<GlobalBinding>& prologVarBindings);
=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp 2012-08-14 11:13:50 +0000
+++ src/compiler/translator/translator.cpp 2012-08-16 18:30:28 +0000
@@ -916,7 +916,7 @@
*******************************************************************************/
inline bool inUDFBody()
{
- return !theCurrentPrologVFDecl.isNull();
+ return (!theCurrentPrologVFDecl.isNull() && theCurrentPrologVFDecl.isUDF());
}
@@ -3246,21 +3246,105 @@
continue;
}
+#if 1
+ const GlobalVarDecl* var_decl = it->dyn_cast<GlobalVarDecl>().getp();
+
+ if (var_decl != NULL &&
+ theSctx->xquery_version() >= StaticContextConsts::xquery_version_3_0)
+ {
+ const QueryLoc& loc = var_decl->get_location();
+
+ store::Item_t qnameItem;
+ expand_no_default_qname(qnameItem, var_decl->get_var_name(), loc);
+
+ // All vars declared in a module must be in the same namespace as the module
+ if (! theModuleNamespace.empty() &&
+ qnameItem->getNamespace() != theModuleNamespace)
+ {
+ RAISE_ERROR(err::XQST0048, loc, ERROR_PARAMS(qnameItem->getStringValue()));
+ }
+
+ var_expr_t ve = create_var(loc, qnameItem, var_expr::prolog_var);
+
+ if (var_decl->is_extern())
+ ve->set_external(true);
+
+ xqtref_t type;
+ if (var_decl->get_var_type() != NULL)
+ {
+ var_decl->get_var_type()->accept(*this);
+
+ type = pop_tstack();
+
+ ve->set_type(type);
+ }
+
+ AnnotationListParsenode* annotations = var_decl->get_annotations();
+ if (annotations)
+ {
+ if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
+ {
+ RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_Annotations)));
+ }
+
+ annotations->accept(*this);
+
+ if (theAnnotations)
+ {
+ if (ZANN_CONTAINS(fn_private))
+ ve->set_private(true);
+
+ if (ZANN_CONTAINS(zann_assignable))
+ {
+ ve->set_mutable(true);
+ }
+ else if (ZANN_CONTAINS(zann_nonassignable))
+ {
+ ve->set_mutable(false);
+ }
+ else
+ {
+ ve->set_mutable(theSctx->is_feature_set(feature::scripting));
+ }
+ }
+ else
+ {
+ ve->set_mutable(theSctx->is_feature_set(feature::scripting));
+ }
+ }
+
+ theAnnotations = NULL;
+
+ // Put a mapping between the var name and the var_expr in the local sctx.
+ // Raise error if var name exists already in local sctx obj.
+ bind_var(ve, theSctx);
+
+ // Make sure that there is no other prolog var with the same name in any of
+ // modules translated so far.
+ bind_var(ve, theModulesInfo->globalSctx.get());
+
+ // If this is a library module, register the var in the exported sctx as well.
+ if (export_sctx != NULL)
+ bind_var(ve, export_sctx);
+
+ continue;
+ }
+#endif
+
const FunctionDecl* func_decl = it->dyn_cast<FunctionDecl>().getp();
- // skip variable and option declarations.
if (func_decl == NULL)
continue;
- AnnotationListParsenode* lAnns = func_decl->get_annotations();
- if (lAnns)
+ AnnotationListParsenode* annotations = func_decl->get_annotations();
+ if (annotations)
{
if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
{
RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_Annotations)));
}
- lAnns->accept(*this);
+ annotations->accept(*this);
}
const QueryLoc& loc = func_decl->get_location();
@@ -3337,9 +3421,7 @@
}
// Create the function signature.
- bool isVariadic = (theAnnotations ?
- ZANN_CONTAINS(zann_variadic):
- false);
+ bool isVariadic = (theAnnotations ? ZANN_CONTAINS(zann_variadic): false);
signature sig(qnameItem, paramTypes, returnType, isVariadic);
@@ -3713,7 +3795,7 @@
// theCurrentPrologVFDecl might be null in case of inline functions
// inline functions currently can't be sequential anyway
// hence, we can always lazy evaluation
- if (!theCurrentPrologVFDecl.isNull())
+ if (inUDFBody())
{
//lc->setLazyEval(!f->isSequential());
@@ -3744,8 +3826,6 @@
/*******************************************************************************
- VarDecl is used to represent both global and block-local var declarations.
-
Global declarations:
--------------------
@@ -3764,22 +3844,8 @@
Note: the applicable annotations are private vs public, and assignable vs
non-assignable.
-
-
- Local declarations:
- -------------------
-
- VarDeclStatement ::= ("local" Annotation*)? "variable"
- "$" VarName TypeDeclaration? (":=" ExprSingle)?
- ("," "$" VarName TypeDeclaration? (":=" ExprSingle)?)* ";"
-
- Note: The initializing ExprSingle in VarValue must be a non-updating expr.
-
- Note: The applicable annotations are assignable vs non-assignable.
-
- Note: Local var decls may appear only as direct operands of block exprs.
********************************************************************************/
-void* begin_visit(const VarDecl& v)
+void* begin_visit(const GlobalVarDecl& v)
{
TRACE_VISIT();
@@ -3788,81 +3854,40 @@
var_expr_t ve;
- if (v.is_global())
+ if (theSctx->xquery_version() >= StaticContextConsts::xquery_version_3_0)
+ {
+ ve = lookup_var(qnameItem, loc, err::XPST0008);
+
+ assert(ve);
+ }
+ else
{
ve = create_var(loc, qnameItem, var_expr::prolog_var);
if (v.is_extern())
ve->set_external(true);
-
- thePrologGraph.addVarVertex(ve);
- theCurrentPrologVFDecl = PrologGraphVertex(ve);
- }
- else
- {
- if (theNodeStack.top()->get_expr_kind() != block_expr_kind)
- {
- ZORBA_ASSERT(false);
- }
-
- ve = create_var(loc, qnameItem, var_expr::local_var);
- }
-
- push_nodestack(ve.getp());
+ }
+
+ thePrologGraph.addVarVertex(ve);
+ theCurrentPrologVFDecl = PrologGraphVertex(ve);
+
+ push_nodestack(ve);
+
return no_state;
}
-void end_visit(const VarDecl& v, void* /*visit_state*/)
+void end_visit(const GlobalVarDecl& v, void* /*visit_state*/)
{
TRACE_VISIT_OUT();
- if (v.is_global())
- theCurrentPrologVFDecl.setNull();
+ theCurrentPrologVFDecl.setNull();
expr_t initExpr = (v.get_binding_expr() == NULL ? expr_t(NULL) : pop_nodestack());
var_expr_t ve = dynamic_cast<var_expr*>(pop_nodestack().getp());
- if (theAnnotations)
- {
- if (v.is_global())
- {
- if (ZANN_CONTAINS(fn_private))
- ve->set_private(true);
- }
-
- if (ZANN_CONTAINS(zann_assignable))
- {
- ve->set_mutable(true);
- }
- else if (ZANN_CONTAINS(zann_nonassignable))
- {
- ve->set_mutable(false);
- }
- else if (v.is_global())
- {
- ve->set_mutable(theSctx->is_feature_set(feature::scripting));
- }
- }
- else if (v.is_global())
- {
- ve->set_mutable(theSctx->is_feature_set(feature::scripting));
- }
-
- xqtref_t type;
- if (v.get_var_type() != NULL)
- {
- type = pop_tstack();
-
- ve->set_type(type);
- }
-
- // Put a mapping between the var name and the var_expr in the local sctx.
- // Raise error if var name exists already in local sctx obj.
- bind_var(ve, theSctx);
-
- if (v.is_global())
+ if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
{
// All vars declared in a module must be in the same namespace as the module
if (! theModuleNamespace.empty() &&
@@ -3871,57 +3896,72 @@
RAISE_ERROR(err::XQST0048, loc, ERROR_PARAMS(ve->get_name()->getStringValue()));
}
+ if (theAnnotations)
+ {
+ if (ZANN_CONTAINS(fn_private))
+ ve->set_private(true);
+
+ if (ZANN_CONTAINS(zann_assignable))
+ {
+ ve->set_mutable(true);
+ }
+ else if (ZANN_CONTAINS(zann_nonassignable))
+ {
+ ve->set_mutable(false);
+ }
+ else
+ {
+ ve->set_mutable(theSctx->is_feature_set(feature::scripting));
+ }
+ }
+ else
+ {
+ ve->set_mutable(theSctx->is_feature_set(feature::scripting));
+ }
+
+ theAnnotations = NULL;
+
+ // Put a mapping between the var name and the var_expr in the local sctx.
+ // Raise error if var name exists already in local sctx obj.
+ bind_var(ve, theSctx);
+
// Make sure that there is no other prolog var with the same name in any of
// modules translated so far.
bind_var(ve, theModulesInfo->globalSctx.get());
-
- // Make sure the initExpr is a simple expr.
- if (initExpr != NULL)
- {
- expr::checkSimpleExpr(initExpr);
- ve->set_has_initializer(true);
- }
-
+
// If this is a library module, register the var in the exported sctx as well.
if (export_sctx != NULL)
bind_var(ve, export_sctx);
-
-#ifdef ZORBA_WITH_DEBUGGER
- if (initExpr != NULL && theCCB->theDebuggerCommons != NULL)
- {
- QueryLoc lExpandedLocation = expandQueryLoc(v.get_var_name()->get_location(),
- initExpr->get_loc());
-
- wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
- }
-#endif
-
- // The ve and its associated intExpr will be put into var_decl_expr that
- // will creaated by the wrap_in_globalvar_assign() method when it is called
- // at the end of the translation of each module.
- thePrologVars.push_back(GlobalBinding(ve, initExpr, v.is_extern()));
- }
- else
- {
- // The ve and its associated intExpr will be put into var_decl_expr that
- // will be created by the translation of the parent block expr, immediately
- // after returning from this method.
- push_nodestack(ve.getp());
-
-#ifdef ZORBA_WITH_DEBUGGER
- if (initExpr != NULL && theCCB->theDebuggerCommons != NULL)
- {
- QueryLoc lExpandedLocation =
- expandQueryLoc(v.get_var_name()->get_location(), initExpr->get_loc());
-
- wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
- }
-#endif
-
- push_nodestack(initExpr);
- }
-
- theAnnotations = NULL;
+ }
+
+ xqtref_t type;
+ if (v.get_var_type() != NULL)
+ {
+ type = pop_tstack();
+ ve->set_type(type);
+ }
+
+ // Make sure the initExpr is a simple expr.
+ if (initExpr != NULL)
+ {
+ expr::checkSimpleExpr(initExpr);
+ ve->set_has_initializer(true);
+ }
+
+#ifdef ZORBA_WITH_DEBUGGER
+ if (initExpr != NULL && theCCB->theDebuggerCommons != NULL)
+ {
+ QueryLoc lExpandedLocation = expandQueryLoc(v.get_var_name()->get_location(),
+ initExpr->get_loc());
+
+ wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
+ }
+#endif
+
+ // The ve and its associated intExpr will be put into var_decl_expr that
+ // will creaated by the wrap_in_globalvar_assign() method when it is called
+ // at the end of the translation of each module.
+ thePrologVars.push_back(GlobalBinding(ve, initExpr, v.is_extern()));
}
@@ -5487,7 +5527,7 @@
{
v[i]->accept(*this);
- if (dynamic_cast<const VarDecl*>(v[i]) != NULL)
+ if (dynamic_cast<const LocalVarDecl*>(v[i]) != NULL)
{
expr_t val = pop_nodestack();
var_expr_t ve = pop_nodestack().cast<var_expr>();
@@ -5577,12 +5617,86 @@
Note: Each individual var decl in a VarDeclStatement is parsed into a VarDecl
parsenode.
+ Note: The applicable annotations are assignable vs non-assignable.
+
Note: The parser makes sure that if a VarDeclStatement does not appear as a
direct child of a BlockBody, it is wrapped by a BlockBody. Furthermore, the
parser will flatten-out the VarDeclStatement parsenode by placing its children
as direct children of the enclosing BlockBody. As a result, VarDeclStatement
- parsenodes do not appear at all in the final AST.
+ parsenodes do not appear at all in the final AST, and local var decls may
+ appear only as direct operands of block exprs.
********************************************************************************/
+void* begin_visit(const LocalVarDecl& v)
+{
+ TRACE_VISIT();
+
+ store::Item_t qnameItem;
+ expand_no_default_qname(qnameItem, v.get_var_name(), loc);
+
+ if (theNodeStack.top()->get_expr_kind() != block_expr_kind)
+ {
+ ZORBA_ASSERT(false);
+ }
+
+ var_expr_t ve = create_var(loc, qnameItem, var_expr::local_var);
+
+ push_nodestack(ve.getp());
+
+ return no_state;
+}
+
+
+void end_visit(const LocalVarDecl& v, void* /*visit_state*/)
+{
+ TRACE_VISIT_OUT();
+
+ expr_t initExpr = (v.get_binding_expr() == NULL ? expr_t(NULL) : pop_nodestack());
+
+ var_expr_t ve = dynamic_cast<var_expr*>(pop_nodestack().getp());
+
+ if (theAnnotations)
+ {
+ if (ZANN_CONTAINS(zann_assignable))
+ {
+ ve->set_mutable(true);
+ }
+ else if (ZANN_CONTAINS(zann_nonassignable))
+ {
+ ve->set_mutable(false);
+ }
+ }
+
+ xqtref_t type;
+ if (v.get_var_type() != NULL)
+ {
+ type = pop_tstack();
+
+ ve->set_type(type);
+ }
+
+ // Put a mapping between the var name and the var_expr in the local sctx.
+ // Raise error if var name exists already in local sctx obj.
+ bind_var(ve, theSctx);
+
+ // The ve and its associated intExpr will be put into var_decl_expr that
+ // will be created by the translation of the parent block expr, immediately
+ // after returning from this method.
+ push_nodestack(ve.getp());
+
+#ifdef ZORBA_WITH_DEBUGGER
+ if (initExpr != NULL && theCCB->theDebuggerCommons != NULL)
+ {
+ QueryLoc lExpandedLocation =
+ expandQueryLoc(v.get_var_name()->get_location(), initExpr->get_loc());
+
+ wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
+ }
+#endif
+
+ push_nodestack(initExpr);
+
+ theAnnotations = NULL;
+}
/*******************************************************************************
@@ -10330,8 +10444,7 @@
// as a non-leaf function.
if (f->isUdf())
{
- if (! theCurrentPrologVFDecl.isNull() &&
- theCurrentPrologVFDecl.getKind() == PrologGraphVertex::FUN)
+ if (inUDFBody())
{
function* f1 = const_cast<function*>(theCurrentPrologVFDecl.getFunction());
user_function* udf = dynamic_cast<user_function*>(f1);
=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp 2012-08-14 11:13:50 +0000
+++ src/context/static_context.cpp 2012-08-16 18:30:28 +0000
@@ -210,8 +210,6 @@
theHasInitializer(v->has_initializer()),
theVarExpr(v.getp())
{
- if (theKind == var_expr::prolog_var)
- v->set_var_info(this);
}
@@ -2198,12 +2196,25 @@
VarInfo_t vi = varExpr->get_var_info();
if (vi == NULL)
+ {
vi = new VarInfo(varExpr);
- if (!theVariablesMap->insert(qname, vi))
+ if (!theVariablesMap->insert(qname, vi))
+ {
+ throw XQUERY_EXCEPTION_VAR(err,
+ ERROR_PARAMS(qname->getStringValue()), ERROR_LOC(loc));
+ }
+
+ if (varExpr->get_kind() == var_expr::prolog_var)
+ varExpr->set_var_info(vi);
+ }
+ else
{
- throw XQUERY_EXCEPTION_VAR(err,
- ERROR_PARAMS(qname->getStringValue()), ERROR_LOC(loc));
+ if (!theVariablesMap->insert(qname, vi))
+ {
+ throw XQUERY_EXCEPTION_VAR(err,
+ ERROR_PARAMS(qname->getStringValue()), ERROR_LOC(loc));
+ }
}
}
=== modified file 'test/rbkt/Queries/CMakeLists.txt'
--- test/rbkt/Queries/CMakeLists.txt 2012-08-14 11:13:50 +0000
+++ test/rbkt/Queries/CMakeLists.txt 2012-08-16 18:30:28 +0000
@@ -555,10 +555,7 @@
EXPECTED_FAILURE(test/rbkt/zorba/reference/reference_5 868640)
# external variable default expected failures
-EXPECTED_FAILURE(test/rbkt/zorba/ext_var/w3c/extvardef-010 900688) # forward references not implemented
-EXPECTED_FAILURE(test/rbkt/zorba/ext_var/w3c/extvardef-011 900688) # forward references not implemented -> cycles cannot be detected
EXPECTED_FAILURE(test/rbkt/zorba/ext_var/w3c/extvardef-014 923672) # not possible to set context item for rbkt tests
-EXPECTED_FAILURE(test/rbkt/zorba/ext_var/w3c/extvardef-022 900688) # forward references not implemented
EXPECTED_FAILURE(test/rbkt/zorba/ext_var/w3c/extvardef-015 923686)
EXPECTED_FAILURE(test/rbkt/zorba/ext_var/w3c/extvardef-016 923686)
=== modified file 'test/rbkt/Queries/zorba/ext_var/w3c/extvardef-011.xq'
--- test/rbkt/Queries/zorba/ext_var/w3c/extvardef-011.xq 2011-12-06 15:13:50 +0000
+++ test/rbkt/Queries/zorba/ext_var/w3c/extvardef-011.xq 2012-08-16 18:30:28 +0000
@@ -1,3 +1,4 @@
declare variable $a := $x;
declare variable $x external := $a + $b;
+declare variable $b := 1;
$x
=== modified file 'test/rbkt/Queries/zorba/ext_var/w3c/extvardef-014.xq'
--- test/rbkt/Queries/zorba/ext_var/w3c/extvardef-014.xq 2011-12-06 15:13:50 +0000
+++ test/rbkt/Queries/zorba/ext_var/w3c/extvardef-014.xq 2012-08-16 18:30:28 +0000
@@ -1,3 +1,4 @@
declare variable $x external := /works/employee[@name eq "Jane Doe 1"];
+
fn:count($x)
=== modified file 'test/rbkt/Queries/zorba/ext_var/w3c/extvardef-015.xq'
--- test/rbkt/Queries/zorba/ext_var/w3c/extvardef-015.xq 2012-01-30 11:27:45 +0000
+++ test/rbkt/Queries/zorba/ext_var/w3c/extvardef-015.xq 2012-08-16 18:30:28 +0000
@@ -1,4 +1,7 @@
declare variable $y := (<a>1</a>,<a>2</a>,<a>3</a>,<a>4</a>,<a>5</a>,<a>6</a>,<a>7</a>,<a>8</a>,<a>9</a>,<a>10</a>);
+
declare context item := $y[3];
+
declare variable $x external := fn:position();
+
$x
=== modified file 'test/rbkt/Queries/zorba/ext_var/w3c/extvardef-016.xq'
--- test/rbkt/Queries/zorba/ext_var/w3c/extvardef-016.xq 2012-01-30 11:27:45 +0000
+++ test/rbkt/Queries/zorba/ext_var/w3c/extvardef-016.xq 2012-08-16 18:30:28 +0000
@@ -1,4 +1,7 @@
declare variable $y := (<a>1</a>,<a>2</a>,<a>3</a>,<a>4</a>,<a>5</a>,<a>6</a>,<a>7</a>,<a>8</a>,<a>9</a>,<a>10</a>);
+
declare context item := $y;
+
declare variable $x external := fn:last();
+
$x
=== modified file 'test/rbkt/Queries/zorba/ext_var/w3c/extvardef-022.xq'
--- test/rbkt/Queries/zorba/ext_var/w3c/extvardef-022.xq 2011-12-06 15:13:50 +0000
+++ test/rbkt/Queries/zorba/ext_var/w3c/extvardef-022.xq 2012-08-16 18:30:28 +0000
@@ -1,5 +1,8 @@
-declare function local:foo() {
+declare function local:foo()
+{
$x
};
+
declare variable $x external := 5;
-$y instance of xs:decimal
+
+local:foo()
Follow ups