XQuilla/include/xqilla/functions/XQUserFunction.hpp

206 lines
7 KiB
C++
Raw Normal View History

2020-02-17 21:05:20 +00:00
/*
2020-02-17 21:22:42 +00:00
* Copyright (c) 2001, 2008,
2020-02-17 21:05:20 +00:00
* DecisionSoft Limited. All rights reserved.
2020-02-17 21:24:47 +00:00
* Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
2020-02-17 21:23:16 +00:00
*
2020-02-17 21:05:20 +00:00
*
2020-02-17 21:12:51 +00:00
* 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
2020-02-17 21:05:20 +00:00
*
2020-02-17 21:12:51 +00:00
* 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.
2020-02-17 21:05:20 +00:00
*/
2020-02-17 21:11:31 +00:00
#ifndef XQUSERFUNCTION_HPP
#define XQUSERFUNCTION_HPP
2020-02-17 21:05:20 +00:00
#include <xqilla/framework/XQillaExport.hpp>
#include <xqilla/functions/FuncFactory.hpp>
2020-02-17 21:11:31 +00:00
#include <xqilla/functions/ExternalFunction.hpp>
2020-02-17 21:05:20 +00:00
#include <xqilla/ast/XQFunction.hpp>
2020-02-17 21:11:31 +00:00
#include <xqilla/ast/StaticAnalysis.hpp>
2020-02-17 21:05:20 +00:00
2020-02-17 21:17:06 +00:00
class XQUserFunction;
2020-02-17 21:22:42 +00:00
class XQQuery;
class FunctionSignature;
class DocumentCache;
class VarStoreImpl;
2020-02-17 21:17:06 +00:00
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_;
};
2020-02-17 21:05:20 +00:00
class XQILLA_API XQUserFunction : public FuncFactory, public LocationInfo
{
public:
2020-02-17 21:22:42 +00:00
class XQILLA_API Mode : public LocationInfo
2020-02-17 21:05:20 +00:00
{
public:
2020-02-17 21:17:06 +00:00
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_; }
2020-02-17 21:05:20 +00:00
2020-02-17 21:11:31 +00:00
const XMLCh *getURI() const { return uri_; }
2020-02-17 21:17:06 +00:00
void setURI(const XMLCh *uri) { uri_ = uri; }
2020-02-17 21:11:31 +00:00
const XMLCh *getName() const { return name_; }
2020-02-17 21:17:06 +00:00
void setName(const XMLCh *name) { name_ = name; }
const XMLCh *getQName() const { return qname_; }
2020-02-17 21:11:31 +00:00
2020-02-17 21:17:06 +00:00
bool equals(const Mode *o) const;
2020-02-17 21:11:31 +00:00
void staticResolution(StaticContext* context);
private:
2020-02-17 21:17:06 +00:00
State state_;
2020-02-17 21:11:31 +00:00
const XMLCh *qname_, *uri_, *name_;
2020-02-17 21:05:20 +00:00
};
2020-02-17 21:17:06 +00:00
typedef std::vector<Mode*,XQillaAllocator<Mode*> > ModeList;
2020-02-17 21:05:20 +00:00
2020-02-17 21:17:06 +00:00
// Constructor for an XQuery function
2020-02-17 21:22:42 +00:00
XQUserFunction(const XMLCh *qname, FunctionSignature *signature, ASTNode *body, bool isGlobal, XPath2MemoryManager *mm);
2020-02-17 21:17:06 +00:00
// Constructor for an XQuery template
2020-02-17 21:22:42 +00:00
XQUserFunction(const XMLCh *qname, VectorOfASTNodes *pattern, FunctionSignature *signature, ASTNode *body, XPath2MemoryManager *mm);
2020-02-17 21:05:20 +00:00
// from FuncFactory
virtual ASTNode *createInstance(const VectorOfASTNodes &args, XPath2MemoryManager* expr) const;
2020-02-17 21:17:06 +00:00
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; }
2020-02-17 21:05:20 +00:00
2020-02-17 21:22:42 +00:00
FunctionSignature *getSignature() const { return signature_; }
2020-02-17 21:17:06 +00:00
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_; }
2020-02-17 21:05:20 +00:00
2020-02-17 21:22:42 +00:00
bool isDelayed() const { return delayed_; }
void setDelayed(bool v) { delayed_ = v; }
void resolveName(StaticContext *context);
2020-02-17 21:05:20 +00:00
/// 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);
2020-02-17 21:17:06 +00:00
void staticTypingOnce(StaticContext *context, StaticTyper *styper);
void resetStaticTypingOnce();
void staticTyping(StaticContext *context, StaticTyper *styper);
2020-02-17 21:05:20 +00:00
2020-02-17 21:11:31 +00:00
void setFunctionBody(ASTNode* value) { body_ = value; }
void setModuleDocumentCache(DocumentCache* docCache) { moduleDocCache_ = docCache; }
2020-02-17 21:05:20 +00:00
2020-02-17 21:11:31 +00:00
const ASTNode *getFunctionBody() const { return body_; }
const ExternalFunction *getExternalFunction() const { return exFunc_; }
DocumentCache *getModuleDocumentCache() const { return moduleDocCache_; }
2020-02-17 21:17:06 +00:00
const StaticAnalysis &getBodyStaticAnalysis() const { return src_; }
XPath2MemoryManager *getMemoryManager() const { return memMgr_; }
static void staticTypeFunctionCalls(ASTNode *item, StaticContext *context, StaticTyper *styper);
2020-02-17 21:05:20 +00:00
static const XMLCh XMLChXQueryLocalFunctionsURI[];
protected:
2020-02-17 21:17:06 +00:00
// Constructor for copying
XQUserFunction(const XQUserFunction *o, XPath2MemoryManager *mm);
// Implementation for releasing
void releaseImpl();
2020-02-17 21:11:31 +00:00
ASTNode *body_;
const ExternalFunction *exFunc_;
2020-02-17 21:17:06 +00:00
const XMLCh *qname_;
VectorOfASTNodes *pattern_;
ASTNode *templateInstance_;
ModeList *modes_;
2020-02-17 21:22:42 +00:00
FunctionSignature *signature_;
2020-02-17 21:17:06 +00:00
bool isGlobal_;
bool isTemplate_;
2020-02-17 21:11:31 +00:00
XPath2MemoryManager *memMgr_;
StaticAnalysis src_;
2020-02-17 21:22:42 +00:00
enum StaticTypingStatus { BEFORE, DURING, AFTER } staticTyped_;
2020-02-17 21:17:06 +00:00
bool recursive_;
2020-02-17 21:22:42 +00:00
bool delayed_;
2020-02-17 21:11:31 +00:00
DocumentCache *moduleDocCache_;
2020-02-17 21:17:06 +00:00
friend class XQUserFunctionInstance;
friend class ASTCopier;
friend class ASTReleaser;
2020-02-17 21:05:20 +00:00
};
2020-02-17 21:22:42 +00:00
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_;
};
2020-02-17 21:11:31 +00:00
#endif