Files
create/src/App/Expression.h
Zheng, Lei 38c47d6e95 Expression: split Expression.h to ExpressionParser.h
Split Expression details into a separate header to reduce recompilation
time on changes.
2019-09-28 15:30:41 +02:00

212 lines
8.1 KiB
C++

/***************************************************************************
* Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef EXPRESSION_H
#define EXPRESSION_H
#include <string>
#include <boost/tuple/tuple.hpp>
#include <Base/Exception.h>
#include <Base/Unit.h>
#include <App/PropertyLinks.h>
#include <App/ObjectIdentifier.h>
#include <Base/BaseClass.h>
#include <Base/Quantity.h>
#include <set>
#include <deque>
#include <App/Range.h>
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Woverloaded-virtual"
#endif
namespace App {
class DocumentObject;
class Expression;
class Document;
typedef std::unique_ptr<Expression> ExpressionPtr;
AppExport bool isAnyEqual(const App::any &v1, const App::any &v2);
AppExport Base::Quantity anyToQuantity(const App::any &value, const char *errmsg = 0);
typedef std::map<App::DocumentObject*, std::map<std::string, std::vector<ObjectIdentifier> > > ExpressionDeps;
class AppExport ExpressionVisitor {
public:
virtual ~ExpressionVisitor() {}
virtual void visit(Expression &e) = 0;
virtual void aboutToChange() {}
virtual int changed() const { return 0;}
virtual void reset() {}
virtual App::PropertyLinkBase* getPropertyLink() {return 0;}
protected:
void getIdentifiers(Expression &e, std::set<App::ObjectIdentifier> &);
void getDeps(Expression &e, ExpressionDeps &);
void getDepObjects(Expression &e, std::set<App::DocumentObject*> &, std::vector<std::string> *);
bool adjustLinks(Expression &e, const std::set<App::DocumentObject*> &inList);
bool relabeledDocument(Expression &e, const std::string &oldName, const std::string &newName);
bool renameObjectIdentifier(Expression &e,
const std::map<ObjectIdentifier,ObjectIdentifier> &, const ObjectIdentifier &);
void collectReplacement(Expression &e, std::map<ObjectIdentifier,ObjectIdentifier> &,
const App::DocumentObject *parent, App::DocumentObject *oldObj, App::DocumentObject *newObj) const;
bool updateElementReference(Expression &e, App::DocumentObject *feature,bool reverse);
void importSubNames(Expression &e, const ObjectIdentifier::SubNameMap &subNameMap);
void updateLabelReference(Expression &e, App::DocumentObject *obj,
const std::string &ref, const char *newLabel);
void moveCells(Expression &e, const CellAddress &address, int rowCount, int colCount);
void offsetCells(Expression &e, int rowOffset, int colOffset);
};
template<class P> class ExpressionModifier : public ExpressionVisitor {
public:
ExpressionModifier(P & _prop)
: prop(_prop)
, propLink(Base::freecad_dynamic_cast<App::PropertyLinkBase>(&prop))
, signaller(_prop,false)
, _changed(0)
{}
virtual ~ExpressionModifier() { }
virtual void aboutToChange() override{
++_changed;
signaller.aboutToChange();
}
virtual int changed() const override { return _changed; }
virtual void reset() override {_changed = 0;}
virtual App::PropertyLinkBase* getPropertyLink() override {return propLink;}
protected:
P & prop;
App::PropertyLinkBase *propLink;
typename AtomicPropertyChangeInterface<P>::AtomicPropertyChange signaller;
int _changed;
};
/**
* Base class for expressions.
*
*/
class AppExport Expression : public Base::BaseClass {
TYPESYSTEM_HEADER();
public:
Expression(const App::DocumentObject * _owner);
virtual ~Expression();
virtual bool isTouched() const { return false; }
virtual Expression * eval() const = 0;
virtual std::string toString(bool persistent=false) const = 0;
static Expression * parse(const App::DocumentObject * owner, const std::string& buffer);
Expression * copy() const;
virtual int priority() const { return 0; }
void getIdentifiers(std::set<App::ObjectIdentifier> &) const;
std::set<App::ObjectIdentifier> getIdentifiers() const;
void getDeps(ExpressionDeps &deps) const;
ExpressionDeps getDeps() const;
std::set<App::DocumentObject*> getDepObjects(std::vector<std::string> *labels=0) const;
void getDepObjects(std::set<App::DocumentObject*> &, std::vector<std::string> *labels=0) const;
ExpressionPtr importSubNames(const std::map<std::string,std::string> &nameMap) const;
ExpressionPtr updateLabelReference(App::DocumentObject *obj,
const std::string &ref, const char *newLabel) const;
ExpressionPtr replaceObject(const App::DocumentObject *parent,
App::DocumentObject *oldObj, App::DocumentObject *newObj) const;
bool adjustLinks(const std::set<App::DocumentObject*> &inList);
virtual Expression * simplify() const = 0;
void visit(ExpressionVisitor & v);
class Exception : public Base::Exception {
public:
Exception(const char *sMessage) : Base::Exception(sMessage) { }
};
App::DocumentObject * getOwner() const { return owner; }
virtual boost::any getValueAsAny() const = 0;
virtual Py::Object getPyValue() const = 0;
bool isSame(const Expression &other) const;
friend ExpressionVisitor;
protected:
virtual Expression *_copy() const = 0;
virtual void _getDeps(ExpressionDeps &) const {}
virtual void _getDepObjects(std::set<App::DocumentObject*> &, std::vector<std::string> *) const {}
virtual void _getIdentifiers(std::set<App::ObjectIdentifier> &) const {}
virtual bool _adjustLinks(const std::set<App::DocumentObject*> &, ExpressionVisitor &) {return false;}
virtual bool _updateElementReference(App::DocumentObject *,bool,ExpressionVisitor &) {return false;}
virtual bool _relabeledDocument(const std::string &, const std::string &, ExpressionVisitor &) {return false;}
virtual void _importSubNames(const ObjectIdentifier::SubNameMap &) {}
virtual void _updateLabelReference(App::DocumentObject *, const std::string &, const char *) {}
virtual bool _renameObjectIdentifier(const std::map<ObjectIdentifier,ObjectIdentifier> &,
const ObjectIdentifier &, ExpressionVisitor &) {return false;}
virtual void _collectReplacement(std::map<ObjectIdentifier,ObjectIdentifier> &,
const App::DocumentObject *parent, App::DocumentObject *oldObj, App::DocumentObject *newObj) const
{
(void)parent;
(void)oldObj;
(void)newObj;
}
virtual void _moveCells(const CellAddress &, int, int, ExpressionVisitor &) {}
virtual void _offsetCells(int, int, ExpressionVisitor &) {}
virtual void _visit(ExpressionVisitor &) {}
protected:
App::DocumentObject * owner; /**< The document object used to access unqualified variables (i.e local scope) */
public:
std::string comment;
};
}
#if defined(__clang__)
# pragma clang diagnostic pop
#endif
#endif // EXPRESSION_H