Commit 6237bbb4 authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

Fixed rewriting for grouped properties.

parent 39071041
......@@ -58,7 +58,7 @@ bool ChangePropertyVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
const quint32 objectStart = ast->firstSourceLocation().offset;
if (objectStart == m_parentLocation) {
replaceInMembers(ast->initializer);
replaceInMembers(ast->initializer, m_name);
return false;
}
......@@ -73,30 +73,39 @@ bool ChangePropertyVisitor::visit(QmlJS::AST::UiObjectBinding *ast)
const quint32 objectStart = ast->qualifiedTypeNameId->identifierToken.offset;
if (objectStart == m_parentLocation) {
replaceInMembers(ast->initializer);
replaceInMembers(ast->initializer, m_name);
return false;
}
return !didRewriting();
}
void ChangePropertyVisitor::replaceInMembers(UiObjectInitializer *initializer)
void ChangePropertyVisitor::replaceInMembers(UiObjectInitializer *initializer,
const QString &propertyName)
{
QString prefix, suffix;
int dotIdx = propertyName.indexOf(QLatin1Char('.'));
if (dotIdx != -1) {
prefix = propertyName.left(dotIdx);
suffix = propertyName.mid(dotIdx + 1);
}
for (UiObjectMemberList *members = initializer->members; members; members = members->next) {
UiObjectMember *propertyMember = members->member;
UiObjectMember *member = members->member;
if (isMatchingPropertyMember(propertyMember)) {
// for non-grouped properties:
if (isMatchingPropertyMember(propertyName, member)) {
switch (m_propertyType) {
case QmlRefactoring::ArrayBinding:
insertIntoArray(cast<UiArrayBinding*>(propertyMember));
insertIntoArray(cast<UiArrayBinding*>(member));
break;
case QmlRefactoring::ObjectBinding:
replaceMemberValue(propertyMember, false);
replaceMemberValue(member, false);
break;
case QmlRefactoring::ScriptBinding:
replaceMemberValue(propertyMember, nextMemberOnSameLine(members));
replaceMemberValue(member, nextMemberOnSameLine(members));
break;
default:
......@@ -105,6 +114,14 @@ void ChangePropertyVisitor::replaceInMembers(UiObjectInitializer *initializer)
break;
}
// for grouped properties:
else if (!prefix.isEmpty()) {
if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) {
if (flatten(def->qualifiedTypeNameId) == prefix) {
replaceInMembers(def->initializer, suffix);
}
}
}
}
}
......@@ -147,16 +164,17 @@ void ChangePropertyVisitor::replaceMemberValue(UiObjectMember *propertyMember, b
setDidRewriting(true);
}
bool ChangePropertyVisitor::isMatchingPropertyMember(QmlJS::AST::UiObjectMember *member) const
bool ChangePropertyVisitor::isMatchingPropertyMember(const QString &propName,
UiObjectMember *member)
{
if (UiObjectBinding *objectBinding = AST::cast<UiObjectBinding *>(member)) {
return m_name == flatten(objectBinding->qualifiedId);
return propName == flatten(objectBinding->qualifiedId);
} else if (UiScriptBinding *scriptBinding = AST::cast<UiScriptBinding *>(member)) {
return m_name == flatten(scriptBinding->qualifiedId);
return propName == flatten(scriptBinding->qualifiedId);
} else if (UiArrayBinding *arrayBinding = AST::cast<UiArrayBinding *>(member)) {
return m_name == flatten(arrayBinding->qualifiedId);
return propName == flatten(arrayBinding->qualifiedId);
} else if (UiPublicMember *publicMember = AST::cast<UiPublicMember *>(member)) {
return m_name == publicMember->name->asString();
return propName == publicMember->name->asString();
} else {
return false;
}
......
......@@ -50,9 +50,11 @@ protected:
virtual bool visit(QmlJS::AST::UiObjectBinding *ast);
private:
void replaceInMembers(QmlJS::AST::UiObjectInitializer *initializer);
void replaceInMembers(QmlJS::AST::UiObjectInitializer *initializer,
const QString &propertyName);
void replaceMemberValue(QmlJS::AST::UiObjectMember *propertyMember, bool needsSemicolon);
bool isMatchingPropertyMember(QmlJS::AST::UiObjectMember *member) const;
static bool isMatchingPropertyMember(const QString &propName,
QmlJS::AST::UiObjectMember *member);
static bool nextMemberOnSameLine(QmlJS::AST::UiObjectMemberList *members);
void insertIntoArray(QmlJS::AST::UiArrayBinding* ast);
......
......@@ -65,35 +65,68 @@ bool RemovePropertyVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
void RemovePropertyVisitor::removeFrom(QmlJS::AST::UiObjectInitializer *ast)
{
UiObjectMember *previousMember = 0, *wantedMember = 0, *nextMember = 0;
QString prefix;
int dotIdx = propertyName.indexOf(QLatin1Char('.'));
if (dotIdx != -1)
prefix = propertyName.left(dotIdx);
for (UiObjectMemberList *it = ast->members; it; it = it->next) {
if (memberNameMatchesPropertyName(it->member)) {
wantedMember = it->member;
UiObjectMember *member = it->member;
if (it->next)
nextMember = it->next->member;
break;
// run full name match (for ungrouped properties):
if (memberNameMatchesPropertyName(propertyName, member)) {
removeMember(member);
}
// check for grouped properties:
else if (!prefix.isEmpty()) {
if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) {
if (flatten(def->qualifiedTypeNameId) == prefix) {
removeGroupedProperty(def);
}
}
}
}
}
void RemovePropertyVisitor::removeGroupedProperty(UiObjectDefinition *ast)
{
int dotIdx = propertyName.indexOf(QLatin1Char('.'));
if (dotIdx == -1)
return;
previousMember = it->member;
const QString propName = propertyName.mid(dotIdx + 1);
UiObjectMember *wanted = 0;
unsigned memberCount = 0;
for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) {
++memberCount;
UiObjectMember *member = it->member;
if (!wanted && memberNameMatchesPropertyName(propName, member)) {
wanted = member;
}
}
if (!wantedMember)
if (!wanted)
return;
if (memberCount == 1)
removeMember(ast);
else
removeMember(wanted);
}
int start = wantedMember->firstSourceLocation().offset;
int end = wantedMember->lastSourceLocation().end();
void RemovePropertyVisitor::removeMember(UiObjectMember *member)
{
int start = member->firstSourceLocation().offset;
int end = member->lastSourceLocation().end();
includeSurroundingWhitespace(start, end);
replace(start, end - start, QLatin1String(""));
setDidRewriting(true);
}
bool RemovePropertyVisitor::memberNameMatchesPropertyName(QmlJS::AST::UiObjectMember *ast) const
bool RemovePropertyVisitor::memberNameMatchesPropertyName(const QString &propertyName, UiObjectMember *ast)
{
if (UiPublicMember *publicMember = cast<UiPublicMember*>(ast))
return publicMember->name->asString() == propertyName;
......
......@@ -50,7 +50,10 @@ protected:
private:
void removeFrom(QmlJS::AST::UiObjectInitializer *ast);
bool memberNameMatchesPropertyName(QmlJS::AST::UiObjectMember *ast) const;
static bool memberNameMatchesPropertyName(const QString &propertyName,
QmlJS::AST::UiObjectMember *ast);
void removeGroupedProperty(QmlJS::AST::UiObjectDefinition *ast);
void removeMember(QmlJS::AST::UiObjectMember *ast);
private:
quint32 parentLocation;
......
......@@ -545,11 +545,11 @@ void TestCore::testRewriterGroupedProperties()
" pointSize: 10\n"
" underline: true\n"
" }\n"
"}");
"}\n");
QPlainTextEdit textEdit1;
textEdit1.setPlainText(qmlString);
NotIndentingTextEditModifier modifier1(&textEdit1);
QPlainTextEdit textEdit;
textEdit.setPlainText(qmlString);
NotIndentingTextEditModifier modifier1(&textEdit);
QScopedPointer<Model> model1(Model::create("Qt/Text"));
......@@ -565,6 +565,22 @@ void TestCore::testRewriterGroupedProperties()
ModelNode rootModelNode = testRewriterView1->rootModelNode();
QCOMPARE(rootModelNode.property(QLatin1String("font.pointSize")).toVariantProperty().value().toDouble(), 10.0);
QCOMPARE(rootModelNode.property(QLatin1String("font.underline")).toVariantProperty().value().toBool(), true);
rootModelNode.removeProperty(QLatin1String("font.underline"));
QCOMPARE(rootModelNode.property(QLatin1String("font.pointSize")).toVariantProperty().value().toDouble(), 10.0);
QVERIFY(!rootModelNode.hasProperty(QLatin1String("font.underline")));
rootModelNode.variantProperty(QLatin1String("font.pointSize")).setValue(20.0);
QCOMPARE(rootModelNode.property(QLatin1String("font.pointSize")).toVariantProperty().value().toDouble(), 20.0);
rootModelNode.removeProperty(QLatin1String("font.pointSize"));
const QLatin1String expected("\n"
"import Qt 4.6\n"
"\n"
"Text {\n"
"}\n");
QCOMPARE(textEdit.toPlainText(), expected);
}
void TestCore::loadSubItems()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment