Commit 033b711d authored by Thomas Hartmann's avatar Thomas Hartmann

QmlJS: Adding checks for .ui.qml files

Change-Id: I88eab65e1c1187ffd5a88fb5c9780d0156a17729
Reviewed-by: default avatarFawzi Mohamed <fawzi.mohamed@digia.com>
parent b4a2bd6b
......@@ -527,6 +527,21 @@ public:
};
class UnsupportedTypesByQmlUi : public QStringList
{
public:
UnsupportedTypesByQmlUi()
{
(*this) << UnsupportedTypesByVisualDesigner()
<< QLatin1String("Binding") << QLatin1String("ShaderEffect")
<< QLatin1String("ShaderEffectSource") << QLatin1String("Canvas")
<< QLatin1String("Component") << QLatin1String("Loader") << QLatin1String("Transition")
<< QLatin1String("PropertyAnimation") << QLatin1String("SequentialAnimation")
<< QLatin1String("ParallelAnimation") << QLatin1String("NumberAnimation");
}
};
class UnsupportedRootObjectTypesByVisualDesigner : public QStringList
{
public:
......@@ -539,11 +554,24 @@ public:
};
class UnsupportedRootObjectTypesByQmlUi : public QStringList
{
public:
UnsupportedRootObjectTypesByQmlUi()
{
(*this) << UnsupportedRootObjectTypesByVisualDesigner()
<< QLatin1String("Window") << QLatin1String("ApplicationWindow");
}
};
} // end of anonymous namespace
Q_GLOBAL_STATIC(VisualAspectsPropertyBlackList, visualAspectsPropertyBlackList)
Q_GLOBAL_STATIC(UnsupportedTypesByVisualDesigner, unsupportedTypesByVisualDesigner)
Q_GLOBAL_STATIC(UnsupportedRootObjectTypesByVisualDesigner, unsupportedRootObjectTypesByVisualDesigner)
Q_GLOBAL_STATIC(UnsupportedRootObjectTypesByQmlUi, unsupportedRootObjectTypesByQmlUi)
Q_GLOBAL_STATIC(UnsupportedTypesByQmlUi, unsupportedTypesByQmlUi)
Check::Check(Document::Ptr doc, const ContextPtr &context)
: _doc(doc)
......@@ -626,12 +654,20 @@ void Check::disableQmlDesignerChecks()
void Check::enableQmlDesignerUiFileChecks()
{
enableMessage(ErrUnsupportedRootTypeInQmlUi);
enableMessage(ErrUnsupportedTypeInQmlUi);
enableMessage(ErrFunctionsNotSupportedInQmlUi);
enableMessage(ErrBlocksNotSupportedInQmlUi);
enableMessage(ErrBehavioursNotSupportedInQmlUi);
}
void Check::disableQmlDesignerUiFileChecks()
{
disableMessage(ErrUnsupportedRootTypeInQmlUi);
disableMessage(ErrUnsupportedTypeInQmlUi);
disableMessage(ErrFunctionsNotSupportedInQmlUi);
disableMessage(ErrBlocksNotSupportedInQmlUi);
disableMessage(ErrBehavioursNotSupportedInQmlUi);
}
bool Check::preVisit(Node *ast)
......@@ -700,8 +736,11 @@ bool Check::visit(UiObjectDefinition *ast)
bool Check::visit(UiObjectBinding *ast)
{
checkScopeObjectMember(ast->qualifiedId);
if (!ast->hasOnToken)
if (!ast->hasOnToken) {
checkProperty(ast->qualifiedId);
} else {
addMessage(ErrBehavioursNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()));
}
visitQmlObject(ast, ast->qualifiedTypeNameId, ast->initializer);
return false;
......@@ -744,6 +783,11 @@ static bool checkTypeForDesignerSupport(UiQualifiedId *typeId)
return unsupportedTypesByVisualDesigner()->contains(getRightMostIdentifier(typeId)->name.toString());
}
static bool checkTypeForQmlUiSupport(UiQualifiedId *typeId)
{
return unsupportedTypesByQmlUi()->contains(getRightMostIdentifier(typeId)->name.toString());
}
static bool checkTopLevelBindingForParentReference(ExpressionStatement *expStmt, const QString &source)
{
if (!expStmt)
......@@ -771,19 +815,27 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId,
const SourceLocation typeErrorLocation = fullLocationForQualifiedId(typeId);
const QString typeName = getRightMostIdentifier(typeId)->name.toString();
if (checkTypeForDesignerSupport(typeId))
addMessage(WarnUnsupportedTypeInVisualDesigner, typeErrorLocation);
addMessage(WarnUnsupportedTypeInVisualDesigner, typeErrorLocation, typeName);
if (checkTypeForQmlUiSupport(typeId))
addMessage(ErrUnsupportedTypeInQmlUi, typeErrorLocation, typeName);
if (m_typeStack.count() > 1 && getRightMostIdentifier(typeId)->name.toString() == QLatin1String("State"))
addMessage(WarnStatesOnlyInRootItemForVisualDesigner, typeErrorLocation);
const QString typeName = getRightMostIdentifier(typeId)->name.toString();
if (m_typeStack.isEmpty()
&& unsupportedRootObjectTypesByVisualDesigner()->contains(typeName))
addMessage(ErrUnsupportedRootTypeInVisualDesigner,
locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()), typeName);
if (m_typeStack.isEmpty()
&& unsupportedRootObjectTypesByQmlUi()->contains(typeName))
addMessage(ErrUnsupportedRootTypeInQmlUi,
locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()), typeName);
bool typeError = false;
if (_importsOk) {
const ObjectValue *prototype = _context->lookupType(_doc.data(), typeId);
......@@ -1033,9 +1085,10 @@ bool Check::visit(FunctionDeclaration *ast)
bool Check::visit(FunctionExpression *ast)
{
SourceLocation locfunc = ast->functionToken;
SourceLocation loclparen = ast->lparenToken;
if (ast->name.isEmpty()) {
SourceLocation locfunc = ast->functionToken;
SourceLocation loclparen = ast->lparenToken;
if (locfunc.isValid() && loclparen.isValid()
&& (locfunc.startLine != loclparen.startLine
|| locfunc.end() + 1 != loclparen.begin())) {
......@@ -1043,6 +1096,8 @@ bool Check::visit(FunctionExpression *ast)
}
}
addMessage(ErrFunctionsNotSupportedInQmlUi, locationFromRange(locfunc, loclparen));
DeclarationsCheck bodyCheck;
addMessages(bodyCheck(ast));
......@@ -1142,6 +1197,8 @@ bool Check::visit(BinaryExpression *ast)
bool Check::visit(Block *ast)
{
addMessage(ErrBlocksNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()));
if (Node *p = parent()) {
if (!cast<UiScriptBinding *>(p)
&& !cast<UiPublicMember *>(p)
......@@ -1483,6 +1540,8 @@ bool Check::visit(CallExpression *ast)
// check for capitalized function name being called
SourceLocation location;
const QString name = functionName(ast->base, &location);
addMessage(ErrFunctionsNotSupportedInQmlUi, location);
if (!name.isEmpty() && name.at(0).isUpper()
&& name != QLatin1String("String")
&& name != QLatin1String("Boolean")
......
......@@ -212,7 +212,7 @@ StaticAnalysisMessages::StaticAnalysisMessages()
newMsg(WarnImperativeCodeNotEditableInVisualDesigner, Warning,
tr("Imperative code is not supported in the Qt Quick Designer."));
newMsg(WarnUnsupportedTypeInVisualDesigner, Warning,
tr("This type is not supported in the Qt Quick Designer."));
tr("This type (%1) is not supported in the Qt Quick Designer."), 1);
newMsg(WarnReferenceToParentItemNotSupportedByVisualDesigner, Warning,
tr("Reference to parent item cannot be resolved correctly by the Qt Quick Designer."));
newMsg(WarnUndefinedValueForVisualDesigner, Warning,
......@@ -223,7 +223,17 @@ StaticAnalysisMessages::StaticAnalysisMessages()
newMsg(WarnAboutQtQuick1InsteadQtQuick2, Warning,
tr("Using Qt Quick 1 code model instead of Qt Quick 2."));
newMsg(ErrUnsupportedRootTypeInVisualDesigner, Error,
tr("This type is not supported as a root element by Qt Quick Designer %1."), 1);
tr("This type (%1) is not supported as a root element by Qt Quick Designer."), 1);
newMsg(ErrUnsupportedRootTypeInQmlUi, Error,
tr("This type (%1) is not supported as a root element of a Qt Quick ui file."), 1);
newMsg(ErrUnsupportedTypeInQmlUi, Error,
tr("This type (%1) is not supported in a Qt Quick ui file."), 1);
newMsg(ErrFunctionsNotSupportedInQmlUi, Error,
tr("Functions are not supported in a Qt Quick ui file."));
newMsg(ErrBlocksNotSupportedInQmlUi, Error,
tr("Java Script blocks are not supported in a Qt Quick ui file."));
newMsg(ErrBehavioursNotSupportedInQmlUi, Error,
tr("Behaviours are not supported in a Qt Quick ui file."));
}
} // anonymous namespace
......
......@@ -99,6 +99,11 @@ enum Type
WarnUndefinedValueForVisualDesigner = 206,
WarnStatesOnlyInRootItemForVisualDesigner = 207,
ErrUnsupportedRootTypeInVisualDesigner = 208,
ErrUnsupportedRootTypeInQmlUi = 220,
ErrUnsupportedTypeInQmlUi = 221,
ErrFunctionsNotSupportedInQmlUi = 222,
ErrBlocksNotSupportedInQmlUi = 223,
ErrBehavioursNotSupportedInQmlUi = 224,
ErrUnknownComponent = 300,
ErrCouldNotResolvePrototypeOf = 301,
ErrCouldNotResolvePrototype = 302,
......
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