forked from qt-creator/qt-creator
qmljsdelta: little cleanup and documentation of the code
This commit is contained in:
@@ -85,6 +85,7 @@ static QString label(UiQualifiedId *id)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return a label string for a AST node that is suitable to compare them.
|
||||||
static QString label(UiObjectMember *member, Document::Ptr doc)
|
static QString label(UiObjectMember *member, Document::Ptr doc)
|
||||||
{
|
{
|
||||||
QString str;
|
QString str;
|
||||||
@@ -112,45 +113,51 @@ static QString label(UiObjectMember *member, Document::Ptr doc)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find nodes in the tree that have the given label */
|
||||||
struct FindObjectMemberWithLabel : public Visitor
|
struct FindObjectMemberWithLabel : public Visitor
|
||||||
{
|
{
|
||||||
virtual void endVisit(UiObjectDefinition *ast) ;
|
virtual void endVisit(UiObjectDefinition *ast) ;
|
||||||
virtual void endVisit(UiObjectBinding *ast) ;
|
virtual void endVisit(UiObjectBinding *ast) ;
|
||||||
|
|
||||||
QList<UiObjectMember *> found;
|
QList<UiObjectMember *> found;
|
||||||
QString cmp;
|
QString label;
|
||||||
Document::Ptr doc;
|
Document::Ptr doc;
|
||||||
};
|
};
|
||||||
|
|
||||||
void FindObjectMemberWithLabel::endVisit(UiObjectDefinition* ast)
|
void FindObjectMemberWithLabel::endVisit(UiObjectDefinition* ast)
|
||||||
{
|
{
|
||||||
if (label(ast, doc) == cmp)
|
if (::label(ast, doc) == label)
|
||||||
found.append(ast);
|
found.append(ast);
|
||||||
}
|
}
|
||||||
void FindObjectMemberWithLabel::endVisit(UiObjectBinding* ast)
|
void FindObjectMemberWithLabel::endVisit(UiObjectBinding* ast)
|
||||||
{
|
{
|
||||||
if (label(ast, doc) == cmp)
|
if (::label(ast, doc) == label)
|
||||||
found.append(ast);
|
found.append(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bidirrection mapping between the old and the new tree nodes
|
||||||
|
*/
|
||||||
struct Map {
|
struct Map {
|
||||||
typedef UiObjectMember*T;
|
typedef UiObjectMember *T1;
|
||||||
QHash<T, T> way1;
|
typedef UiObjectMember *T2;
|
||||||
QHash<T, T> way2;
|
QHash<T1, T2> way1;
|
||||||
void insert(T t1, T t2) {
|
QHash<T2, T1> way2;
|
||||||
way1.insert(t1,t2);
|
void insert(T1 t1, T2 t2) {
|
||||||
way2.insert(t2,t1);
|
way1.insert(t1, t2);
|
||||||
|
way2.insert(t2, t1);
|
||||||
}
|
}
|
||||||
int count() { return way1.count(); }
|
int count() { return way1.count(); }
|
||||||
void operator+=(const Map &other) {
|
void operator+=(const Map &other) {
|
||||||
way1.unite(other.way1);
|
way1.unite(other.way1);
|
||||||
way2.unite(other.way2);
|
way2.unite(other.way2);
|
||||||
}
|
}
|
||||||
bool contains(T t1, T t2) {
|
bool contains(T1 t1, T2 t2) {
|
||||||
return way1.value(t1) == t2;
|
return way1.value(t1) == t2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//return the list of children node of an ast node
|
||||||
static QList<UiObjectMember *> children(UiObjectMember *ast)
|
static QList<UiObjectMember *> children(UiObjectMember *ast)
|
||||||
{
|
{
|
||||||
QList<UiObjectMember *> ret;
|
QList<UiObjectMember *> ret;
|
||||||
@@ -176,7 +183,8 @@ static QList<UiObjectMember *> children(UiObjectMember *ast)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map MatchFragment(UiObjectMember *x, UiObjectMember *y, const Map &M, Document::Ptr doc1, Document::Ptr doc2) {
|
/* build a mapping between nodes of two subtree of an ast. x and y are the root of the two subtrees */
|
||||||
|
static Map buildMapping_helper(UiObjectMember *x, UiObjectMember *y, const Map &M, Document::Ptr doc1, Document::Ptr doc2) {
|
||||||
Map M2;
|
Map M2;
|
||||||
if (M.way1.contains(x))
|
if (M.way1.contains(x))
|
||||||
return M2;
|
return M2;
|
||||||
@@ -194,7 +202,7 @@ Map MatchFragment(UiObjectMember *x, UiObjectMember *y, const Map &M, Document::
|
|||||||
for (int j = 0; j < list2.count(); j++) {
|
for (int j = 0; j < list2.count(); j++) {
|
||||||
if (l != label(list2[j], doc2))
|
if (l != label(list2[j], doc2))
|
||||||
continue;
|
continue;
|
||||||
Map M4 = MatchFragment(list1[i], list2[j], M, doc1, doc2);
|
Map M4 = buildMapping_helper(list1[i], list2[j], M, doc1, doc2);
|
||||||
if (M4.count() > M3.count()) {
|
if (M4.count() > M3.count()) {
|
||||||
M3 = M4;
|
M3 = M4;
|
||||||
foundJ = j;
|
foundJ = j;
|
||||||
@@ -208,7 +216,9 @@ Map MatchFragment(UiObjectMember *x, UiObjectMember *y, const Map &M, Document::
|
|||||||
return M2;
|
return M2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map Mapping(Document::Ptr doc1, Document::Ptr doc2)
|
/* given two AST, build a mapping between the corresponding nodes of the two tree
|
||||||
|
*/
|
||||||
|
static Map buildMapping(Document::Ptr doc1, Document::Ptr doc2)
|
||||||
{
|
{
|
||||||
Map M;
|
Map M;
|
||||||
QList<UiObjectMember *> todo;
|
QList<UiObjectMember *> todo;
|
||||||
@@ -222,14 +232,14 @@ Map Mapping(Document::Ptr doc1, Document::Ptr doc2)
|
|||||||
|
|
||||||
//If this is too slow, we could use some sort of indexing
|
//If this is too slow, we could use some sort of indexing
|
||||||
FindObjectMemberWithLabel v3;
|
FindObjectMemberWithLabel v3;
|
||||||
v3.cmp = label(x, doc1);
|
v3.label = label(x, doc1);
|
||||||
v3.doc = doc2;
|
v3.doc = doc2;
|
||||||
doc2->qmlProgram()->accept(&v3);
|
doc2->qmlProgram()->accept(&v3);
|
||||||
Map M2;
|
Map M2;
|
||||||
foreach (UiObjectMember *y, v3.found) {
|
foreach (UiObjectMember *y, v3.found) {
|
||||||
if (M.way2.contains(y))
|
if (M.way2.contains(y))
|
||||||
continue;
|
continue;
|
||||||
Map M3 = MatchFragment(x, y, M, doc1, doc2);
|
Map M3 = buildMapping_helper(x, y, M, doc1, doc2);
|
||||||
if (M3.count() > M2.count())
|
if (M3.count() > M2.count())
|
||||||
M2 = M3;
|
M2 = M3;
|
||||||
}
|
}
|
||||||
@@ -430,7 +440,7 @@ Delta::DebugIdMap Delta::operator()(const Document::Ptr &doc1, const Document::P
|
|||||||
|
|
||||||
Delta::DebugIdMap newDebuggIds;
|
Delta::DebugIdMap newDebuggIds;
|
||||||
|
|
||||||
Map M = Mapping(doc1, doc2);
|
Map M = buildMapping(doc1, doc2);
|
||||||
|
|
||||||
BuildParentHash parents2;
|
BuildParentHash parents2;
|
||||||
doc2->qmlProgram()->accept(&parents2);
|
doc2->qmlProgram()->accept(&parents2);
|
||||||
|
Reference in New Issue
Block a user