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