XQuilla/include/xqilla/functions/XQUserFunction.hpp
2020-02-17 22:24:47 +01:00

205 lines
7 KiB
C++

/*
* Copyright (c) 2001, 2008,
* DecisionSoft Limited. All rights reserved.
* Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef XQUSERFUNCTION_HPP
#define XQUSERFUNCTION_HPP
#include <xqilla/framework/XQillaExport.hpp>
#include <xqilla/functions/FuncFactory.hpp>
#include <xqilla/functions/ExternalFunction.hpp>
#include <xqilla/ast/XQFunction.hpp>
#include <xqilla/ast/StaticAnalysis.hpp>
class XQUserFunction;
class XQQuery;
class FunctionSignature;
class DocumentCache;
class VarStoreImpl;
class XQILLA_API XQUserFunctionInstance : public XQFunction, public ExternalFunction::Arguments
{
public:
XQUserFunctionInstance(const XQUserFunction *funcDef, const VectorOfASTNodes& args, XPath2MemoryManager *mm);
XQUserFunctionInstance(const XQUserFunction *funcDef, const VectorOfASTNodes& args, bool addReturnCheck, XPath2MemoryManager *mm);
virtual Result getArgument(size_t index, DynamicContext *context) const;
Result createResult(DynamicContext* context, int flags=0) const;
virtual EventGenerator::Ptr generateEvents(EventHandler *events, DynamicContext *context,
bool preserveNS, bool preserveType) const;
ASTNode* staticResolution(StaticContext* context);
virtual ASTNode *staticTypingImpl(StaticContext *context);
virtual PendingUpdateList createUpdateList(DynamicContext *context) const;
void evaluateArguments(VarStoreImpl &scope, DynamicContext *context) const;
const XQUserFunction *getFunctionDefinition() const
{
return funcDef_;
}
void setFunctionDefinition(const XQUserFunction *f) { funcDef_ = f; }
bool getAddReturnCheck() const { return addReturnCheck_; }
protected:
bool addReturnCheck_;
const XQUserFunction *funcDef_;
};
class XQILLA_API XQUserFunction : public FuncFactory, public LocationInfo
{
public:
class XQILLA_API Mode : public LocationInfo
{
public:
enum State {
QNAME,
DEFAULT,
ALL,
CURRENT
};
Mode(const XMLCh *qname) : state_(QNAME), qname_(qname), uri_(0), name_(0) {}
Mode(const XMLCh *uri, const XMLCh *name) : state_(QNAME), qname_(0), uri_(uri), name_(name) {}
Mode(State state) : state_(state), qname_(0), uri_(0), name_(0) {}
Mode(const Mode *o) : state_(o->state_), qname_(o->qname_), uri_(o->uri_), name_(o->name_) {}
State getState() const { return state_; }
const XMLCh *getURI() const { return uri_; }
void setURI(const XMLCh *uri) { uri_ = uri; }
const XMLCh *getName() const { return name_; }
void setName(const XMLCh *name) { name_ = name; }
const XMLCh *getQName() const { return qname_; }
bool equals(const Mode *o) const;
void staticResolution(StaticContext* context);
private:
State state_;
const XMLCh *qname_, *uri_, *name_;
};
typedef std::vector<Mode*,XQillaAllocator<Mode*> > ModeList;
// Constructor for an XQuery function
XQUserFunction(const XMLCh *qname, FunctionSignature *signature, ASTNode *body, bool isGlobal, XPath2MemoryManager *mm);
// Constructor for an XQuery template
XQUserFunction(const XMLCh *qname, VectorOfASTNodes *pattern, FunctionSignature *signature, ASTNode *body, XPath2MemoryManager *mm);
// from FuncFactory
virtual ASTNode *createInstance(const VectorOfASTNodes &args, XPath2MemoryManager* expr) const;
virtual const XMLCh *getQName() const { return qname_; }
void setName(const XMLCh *name) { name_ = name; }
void setURI(const XMLCh *uri) { uri_ = uri; }
VectorOfASTNodes *getPattern() const { return pattern_; }
void setPattern(VectorOfASTNodes *pattern) { pattern_ = pattern; }
ModeList *getModeList() const { return modes_; }
void setModeList(ModeList *modes) { modes_ = modes; }
FunctionSignature *getSignature() const { return signature_; }
ASTNode *getTemplateInstance() const { return templateInstance_; }
void setTemplateInstance(ASTNode *ast) { templateInstance_ = ast; }
bool isGlobal() const { return isGlobal_; }
bool isTemplate() const { return isTemplate_; }
bool isRecursive() const { return recursive_; }
bool isDelayed() const { return delayed_; }
void setDelayed(bool v) { delayed_ = v; }
void resolveName(StaticContext *context);
/// Resolve URIs, give the function a default static type
void staticResolutionStage1(StaticContext* context);
/// Resolve the function body, work out a more static return type
void staticResolutionStage2(StaticContext* context);
void staticTypingOnce(StaticContext *context, StaticTyper *styper);
void resetStaticTypingOnce();
void staticTyping(StaticContext *context, StaticTyper *styper);
void setFunctionBody(ASTNode* value) { body_ = value; }
void setModuleDocumentCache(DocumentCache* docCache) { moduleDocCache_ = docCache; }
const ASTNode *getFunctionBody() const { return body_; }
const ExternalFunction *getExternalFunction() const { return exFunc_; }
DocumentCache *getModuleDocumentCache() const { return moduleDocCache_; }
const StaticAnalysis &getBodyStaticAnalysis() const { return src_; }
XPath2MemoryManager *getMemoryManager() const { return memMgr_; }
static void staticTypeFunctionCalls(ASTNode *item, StaticContext *context, StaticTyper *styper);
static const XMLCh XMLChXQueryLocalFunctionsURI[];
protected:
// Constructor for copying
XQUserFunction(const XQUserFunction *o, XPath2MemoryManager *mm);
// Implementation for releasing
void releaseImpl();
ASTNode *body_;
const ExternalFunction *exFunc_;
const XMLCh *qname_;
VectorOfASTNodes *pattern_;
ASTNode *templateInstance_;
ModeList *modes_;
FunctionSignature *signature_;
bool isGlobal_;
bool isTemplate_;
XPath2MemoryManager *memMgr_;
StaticAnalysis src_;
enum StaticTypingStatus { BEFORE, DURING, AFTER } staticTyped_;
bool recursive_;
bool delayed_;
DocumentCache *moduleDocCache_;
friend class XQUserFunctionInstance;
friend class ASTCopier;
friend class ASTReleaser;
};
class XQILLA_API DelayedFuncFactory : public FuncFactory
{
public:
DelayedFuncFactory(const XMLCh *uri, const XMLCh *name, size_t numArgs,
const XMLCh *body, int line, int column, XQQuery *query);
DelayedFuncFactory(const XMLCh *uri, const XMLCh *name, size_t numArgs,
const char *body, int line, int column, XQQuery *query);
virtual ASTNode *createInstance(const VectorOfASTNodes &args, XPath2MemoryManager* memMgr) const;
bool isParsed() const { return function_ != 0; }
private:
const XMLCh *body_;
const char *body8_;
int line_, column_;
XQQuery *query_;
XQUserFunction *function_;
};
#endif