/**************************************************************************** ** ** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtScxml module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ****************************************************************************/ #ifndef QSCXMLCOMPILER_P_H #define QSCXMLCOMPILER_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "qscxmlcompiler.h" #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE namespace DocumentModel { struct XmlLocation { int line; int column; XmlLocation(int theLine, int theColumn): line(theLine), column(theColumn) {} }; struct If; struct Send; struct Invoke; struct Script; struct AbstractState; struct State; struct Transition; struct HistoryState; struct Scxml; class NodeVisitor; struct Node { XmlLocation xmlLocation; Node(const XmlLocation &theLocation): xmlLocation(theLocation) {} virtual ~Node(); virtual void accept(NodeVisitor *visitor) = 0; virtual If *asIf() { return nullptr; } virtual Send *asSend() { return nullptr; } virtual Invoke *asInvoke() { return nullptr; } virtual Script *asScript() { return nullptr; } virtual State *asState() { return nullptr; } virtual Transition *asTransition() { return nullptr; } virtual HistoryState *asHistoryState() { return nullptr; } virtual Scxml *asScxml() { return nullptr; } AbstractState *asAbstractState(); private: Q_DISABLE_COPY(Node) }; struct DataElement: public Node { QString id; QString src; QString expr; QString content; DataElement(const XmlLocation &xmlLocation): Node(xmlLocation) {} void accept(NodeVisitor *visitor) override; }; struct Param: public Node { QString name; QString expr; QString location; Param(const XmlLocation &xmlLocation): Node(xmlLocation) {} void accept(NodeVisitor *visitor) override; }; struct DoneData: public Node { QString contents; QString expr; QVector params; DoneData(const XmlLocation &xmlLocation): Node(xmlLocation) {} void accept(NodeVisitor *visitor) override; }; struct Instruction: public Node { Instruction(const XmlLocation &xmlLocation): Node(xmlLocation) {} virtual ~Instruction() {} }; typedef QVector InstructionSequence; typedef QVector InstructionSequences; struct Send: public Instruction { QString event; QString eventexpr; QString type; QString typeexpr; QString target; QString targetexpr; QString id; QString idLocation; QString delay; QString delayexpr; QStringList namelist; QVector params; QString content; QString contentexpr; Send(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} Send *asSend() override { return this; } void accept(NodeVisitor *visitor) override; }; struct ScxmlDocument; struct Invoke: public Instruction { QString type; QString typeexpr; QString src; QString srcexpr; QString id; QString idLocation; QStringList namelist; bool autoforward; QVector params; InstructionSequence finalize; QSharedPointer content; Invoke(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} Invoke *asInvoke() override { return this; } void accept(NodeVisitor *visitor) override; }; struct Raise: public Instruction { QString event; Raise(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} void accept(NodeVisitor *visitor) override; }; struct Log: public Instruction { QString label, expr; Log(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} void accept(NodeVisitor *visitor) override; }; struct Script: public Instruction { QString src; QString content; Script(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} Script *asScript() override { return this; } void accept(NodeVisitor *visitor) override; }; struct Assign: public Instruction { QString location; QString expr; QString content; Assign(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} void accept(NodeVisitor *visitor) override; }; struct If: public Instruction { QStringList conditions; InstructionSequences blocks; If(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} If *asIf() override { return this; } void accept(NodeVisitor *visitor) override; }; struct Foreach: public Instruction { QString array; QString item; QString index; InstructionSequence block; Foreach(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} void accept(NodeVisitor *visitor) override; }; struct Cancel: public Instruction { QString sendid; QString sendidexpr; Cancel(const XmlLocation &xmlLocation): Instruction(xmlLocation) {} void accept(NodeVisitor *visitor) override; }; struct StateOrTransition: public Node { StateOrTransition(const XmlLocation &xmlLocation): Node(xmlLocation) {} }; struct StateContainer { StateContainer() : parent(nullptr) {} StateContainer *parent; virtual ~StateContainer() {} virtual void add(StateOrTransition *s) = 0; virtual AbstractState *asAbstractState() { return nullptr; } virtual State *asState() { return nullptr; } virtual Scxml *asScxml() { return nullptr; } }; struct AbstractState: public StateContainer { QString id; AbstractState *asAbstractState() override { return this; } }; struct State: public AbstractState, public StateOrTransition { enum Type { Normal, Parallel, Final }; QStringList initial; QVector dataElements; QVector children; InstructionSequences onEntry; InstructionSequences onExit; DoneData *doneData; QVector invokes; Type type; Transition *initialTransition; // when not set, it is filled during verification State(const XmlLocation &xmlLocation) : StateOrTransition(xmlLocation) , doneData(nullptr) , type(Normal) , initialTransition(nullptr) {} void add(StateOrTransition *s) override { Q_ASSERT(s); children.append(s); } State *asState() override { return this; } void accept(NodeVisitor *visitor) override; }; struct Transition: public StateOrTransition { enum Type { Internal, External, Synthetic }; QStringList events; QScopedPointer condition; QStringList targets; InstructionSequence instructionsOnTransition; Type type; QVector targetStates; // when not set, it is filled during verification Transition(const XmlLocation &xmlLocation) : StateOrTransition(xmlLocation) , type(External) {} Transition *asTransition() override { return this; } void accept(NodeVisitor *visitor) override; }; struct HistoryState: public AbstractState, public StateOrTransition { enum Type { Deep, Shallow }; Type type; QVector children; HistoryState(const XmlLocation &xmlLocation) : StateOrTransition(xmlLocation) , type(Shallow) {} void add(StateOrTransition *s) override { Q_ASSERT(s); children.append(s); } Transition *defaultConfiguration() { return children.isEmpty() ? nullptr : children.first()->asTransition(); } HistoryState *asHistoryState() override { return this; } void accept(NodeVisitor *visitor) override; }; struct Scxml: public StateContainer, public Node { enum DataModelType { NullDataModel, JSDataModel, CppDataModel }; enum BindingMethod { EarlyBinding, LateBinding }; QStringList initial; QString name; DataModelType dataModel; QString cppDataModelClassName; QString cppDataModelHeaderName; BindingMethod binding; QVector children; QVector dataElements; QScopedPointer