texttomodelmerger.h 13.5 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
hjk's avatar
hjk committed
3
4
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8
9
10
11
12
13
14
** 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 Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
15
16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17
18
19
20
21
22
23
24
25
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
con's avatar
con committed
26
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
29
30
31
32

#ifndef TEXTTOMODELMERGER_H
#define TEXTTOMODELMERGER_H

33
#include "qmldesignercorelib_global.h"
34
#include "import.h"
35
36
#include "nodelistproperty.h"
#include "modelnode.h"
37

38
#include <qmljs/qmljsdocument.h>
Christian Kamm's avatar
Christian Kamm committed
39
#include <qmljs/qmljsscopechain.h>
40

41
42
#include <QStringList>
#include <QTimer>
43

44
45
namespace QmlDesigner {

hjk's avatar
hjk committed
46
class RewriterView;
47
48
49
50

namespace Internal {

class DifferenceHandler;
51
class ReadingContext;
52
53
54
55
56
57
58
59
60
61

class TextToModelMerger
{
    TextToModelMerger(const TextToModelMerger&);
    TextToModelMerger &operator=(const TextToModelMerger&);

public:
    TextToModelMerger(RewriterView *reWriterView);
    bool isActive() const;

62
    void setupImports(const QmlJS::Document::Ptr &doc, DifferenceHandler &differenceHandler);
63
    bool load(const QString &data, DifferenceHandler &differenceHandler);
64

65
66
67
    RewriterView *view() const
    { return m_rewriterView; }

Thomas Hartmann's avatar
Thomas Hartmann committed
68
69
    const QmlJS::ScopeChain *scopeChain() const
    { return m_scopeChain.data(); }
70

71
    const QmlJS::Document *document() const
72
73
    { return m_document.data(); }

74
75
76
77
78
protected:
    void setActive(bool active);

public:
    void syncNode(ModelNode &modelNode,
79
80
                  QmlJS::AST::UiObjectMember *astNode,
                  ReadingContext *context,
81
                  DifferenceHandler &differenceHandler);
82
83
84
85
86
    QString syncScriptBinding(ModelNode &modelNode,
                              const QString &prefix,
                              QmlJS::AST::UiScriptBinding *script,
                              ReadingContext *context,
                              DifferenceHandler &differenceHandler);
87
88
89
90
91
92
93
94
    void syncNodeId(ModelNode &modelNode, const QString &astObjectId,
                    DifferenceHandler &differenceHandler);
    void syncNodeProperty(AbstractProperty &modelProperty,
                          QmlJS::AST::UiObjectBinding *binding,
                          ReadingContext *context,
                          DifferenceHandler &differenceHandler);
    void syncExpressionProperty(AbstractProperty &modelProperty,
                                const QString &javascript,
95
                                const QString &astType,
96
97
                                DifferenceHandler &differenceHandler);
    void syncArrayProperty(AbstractProperty &modelProperty,
Erik Verbruggen's avatar
Erik Verbruggen committed
98
                           const QList<QmlJS::AST::UiObjectMember *> &arrayMembers,
99
100
101
                           ReadingContext *context,
                           DifferenceHandler &differenceHandler);
    void syncVariantProperty(AbstractProperty &modelProperty,
102
                             const QVariant &astValue,
103
104
                             const QString &astType,
                             DifferenceHandler &differenceHandler);
105
    void syncNodeListProperty(NodeListProperty &modelListProperty,
106
107
                              const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
                              ReadingContext *context,
108
                              DifferenceHandler &differenceHandler);
109
110
111
    ModelNode createModelNode(const QString &typeName,
                              int majorVersion,
                              int minorVersion,
112
                              bool isImplicitComponent,
113
114
                              QmlJS::AST::UiObjectMember *astNode,
                              ReadingContext *context,
115
                              DifferenceHandler &differenceHandler);
116
117
118
119
120
    QStringList syncGroupedProperties(ModelNode &modelNode,
                                      const QString &name,
                                      QmlJS::AST::UiObjectMemberList *members,
                                      ReadingContext *context,
                                      DifferenceHandler &differenceHandler);
121

122
123
124
125
    void setupComponentDelayed(const ModelNode &node, bool synchron);
    void setupCustomParserNodeDelayed(const ModelNode &node, bool synchron);

    void delayedSetup();
126

127
private:
128
129
130
    void setupCustomParserNode(const ModelNode &node);
    void setupComponent(const ModelNode &node);

131
132
133
134
135
136
    static QString textAt(const QmlJS::Document::Ptr &doc,
                          const QmlJS::AST::SourceLocation &location);
    static QString textAt(const QmlJS::Document::Ptr &doc,
                          const QmlJS::AST::SourceLocation &from,
                          const QmlJS::AST::SourceLocation &to);

137
private:
138
139
    RewriterView *m_rewriterView;
    bool m_isActive;
140
    QSharedPointer<const QmlJS::ScopeChain> m_scopeChain;
141
    QmlJS::Document::Ptr m_document;
142
143
144
    QTimer m_setupTimer;
    QSet<ModelNode> m_setupComponentList;
    QSet<ModelNode> m_setupCustomParserList;
145
146
147
148
149
150
151
152
153
154
155
};

class DifferenceHandler
{
public:
    DifferenceHandler(TextToModelMerger *textToModelMerger):
            m_merger(textToModelMerger)
    {}
    virtual ~DifferenceHandler()
    {}

Friedemann Kleint's avatar
Friedemann Kleint committed
156
157
    virtual void modelMissesImport(const QmlDesigner::Import &import) = 0;
    virtual void importAbsentInQMl(const QmlDesigner::Import &import) = 0;
158
    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty,
159
160
                                          const QString &javascript,
                                          const QString &astType) = 0;
161
    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty,
162
163
                                         const QString &javascript,
                                         const QString &astType) = 0;
164
165
166
    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty,
                                          const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
                                          ReadingContext *context) = 0;
167
168
    virtual void variantValuesDiffer(VariantProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName) = 0;
    virtual void shouldBeVariantProperty(AbstractProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName) = 0;
169
170
171
172
173
174
    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty,
                                      const QString &typeName,
                                      int majorVersion,
                                      int minorVersion,
                                      QmlJS::AST::UiObjectMember *astNode,
                                      ReadingContext *context) = 0;
175
    virtual void modelNodeAbsentFromQml(ModelNode &modelNode) = 0;
176
177
178
179
180
181
182
183
184
185
    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty,
                                                   ReadingContext *context,
                                                   QmlJS::AST::UiObjectMember *arrayMember) = 0;
    virtual void typeDiffers(bool isRootNode,
                             ModelNode &modelNode,
                             const QString &typeName,
                             int majorVersion,
                             int minorVersion,
                             QmlJS::AST::UiObjectMember *astNode,
                             ReadingContext *context) = 0;
186
187
    virtual void propertyAbsentFromQml(AbstractProperty &modelProperty) = 0;
    virtual void idsDiffer(ModelNode &modelNode, const QString &qmlId) = 0;
188
    virtual bool isValidator() const = 0;
189
190
191
192
193
194
195
196
197
198
199
200
201
202

protected:
    TextToModelMerger *m_merger;
};

class ModelValidator: public DifferenceHandler
{
public:
    ModelValidator(TextToModelMerger *textToModelMerger):
            DifferenceHandler(textToModelMerger)
    {}
    ~ModelValidator()
    {}

Friedemann Kleint's avatar
Friedemann Kleint committed
203
204
    virtual void modelMissesImport(const QmlDesigner::Import &import);
    virtual void importAbsentInQMl(const QmlDesigner::Import &import);
205
    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty,
206
207
                                          const QString &javascript,
                                          const QString &astType);
208
    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty,
209
210
                                         const QString &javascript,
                                         const QString &astType);
211
212
213
    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty,
                                          const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
                                          ReadingContext *context);
214
215
    virtual void variantValuesDiffer(VariantProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName);
    virtual void shouldBeVariantProperty(AbstractProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName);
216
217
218
219
220
221
    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty,
                                      const QString &typeName,
                                      int majorVersion,
                                      int minorVersion,
                                      QmlJS::AST::UiObjectMember *astNode,
                                      ReadingContext *context);
222
    virtual void modelNodeAbsentFromQml(ModelNode &modelNode);
223
224
225
226
227
228
229
230
231
232
    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty,
                                                   ReadingContext *context,
                                                   QmlJS::AST::UiObjectMember *arrayMember);
    virtual void typeDiffers(bool isRootNode,
                             ModelNode &modelNode,
                             const QString &typeName,
                             int majorVersion,
                             int minorVersion,
                             QmlJS::AST::UiObjectMember *astNode,
                             ReadingContext *context);
233
234
    virtual void propertyAbsentFromQml(AbstractProperty &modelProperty);
    virtual void idsDiffer(ModelNode &modelNode, const QString &qmlId);
235
    virtual bool isValidator() const {return false; }
236
237
238
239
240
241
242
243
244
245
246
};

class ModelAmender: public DifferenceHandler
{
public:
    ModelAmender(TextToModelMerger *textToModelMerger):
            DifferenceHandler(textToModelMerger)
    {}
    ~ModelAmender()
    {}

Friedemann Kleint's avatar
Friedemann Kleint committed
247
248
    virtual void modelMissesImport(const QmlDesigner::Import &import);
    virtual void importAbsentInQMl(const QmlDesigner::Import &import);
249
    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty,
250
251
                                          const QString &javascript,
                                          const QString &astType);
252
    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty,
253
254
                                         const QString &javascript,
                                         const QString &astType);
255
256
257
    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty,
                                          const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
                                          ReadingContext *context);
258
259
    virtual void variantValuesDiffer(VariantProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicType);
    virtual void shouldBeVariantProperty(AbstractProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName);
260
261
262
263
264
265
    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty,
                                      const QString &typeName,
                                      int majorVersion,
                                      int minorVersion,
                                      QmlJS::AST::UiObjectMember *astNode,
                                      ReadingContext *context);
266
    virtual void modelNodeAbsentFromQml(ModelNode &modelNode);
267
268
269
270
271
272
273
274
275
276
    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty,
                                                   ReadingContext *context,
                                                   QmlJS::AST::UiObjectMember *arrayMember);
    virtual void typeDiffers(bool isRootNode,
                             ModelNode &modelNode,
                             const QString &typeName,
                             int majorVersion,
                             int minorVersion,
                             QmlJS::AST::UiObjectMember *astNode,
                             ReadingContext *context);
277
278
    virtual void propertyAbsentFromQml(AbstractProperty &modelProperty);
    virtual void idsDiffer(ModelNode &modelNode, const QString &qmlId);
279
    virtual bool isValidator() const {return true; }
280
281
282
283
284
285
};

} //Internal
} //QmlDesigner

#endif // TEXTTOMODELMERGER_H