Improve QML error messages
authorAaron Kennedy <aaron.kennedy@nokia.com>
Fri, 6 Jan 2012 12:16:24 +0000 (12:16 +0000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 6 Jan 2012 14:27:10 +0000 (15:27 +0100)
Point at the actual property and method name when raising errors about
them.

Change-Id: Id36df4850b91ae0d225fcda4d101f4b2a073a72e
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
src/declarative/qml/qdeclarativecompiler.cpp
src/declarative/qml/qdeclarativescript.cpp
src/declarative/qml/qdeclarativescript_p.h
tests/auto/declarative/qdeclarativelanguage/data/dynamicMeta.2.errors.txt
tests/auto/declarative/qdeclarativelanguage/data/dynamicMeta.4.errors.txt
tests/auto/declarative/qdeclarativelanguage/data/invalidProperty.errors.txt
tests/auto/declarative/qdeclarativelanguage/data/method.1.errors.txt
tests/auto/declarative/qdeclarativelanguage/data/property.6.errors.txt
tests/auto/declarative/qdeclarativelanguage/data/property.7.errors.txt
tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp

index 1bd714b..3a7a601 100644 (file)
@@ -185,18 +185,20 @@ bool QDeclarativeCompiler::isSignalPropertyName(const QHashedStringRef &name)
     COMPILE_EXCEPTION(property, tr("Error for property \"%1\"").arg(property->name));
     \endcode
 */
-#define COMPILE_EXCEPTION(token, desc) \
+#define COMPILE_EXCEPTION_LOCATION(line, column, desc) \
     {  \
-        QString exceptionDescription; \
         QDeclarativeError error; \
         error.setUrl(output->url); \
-        error.setLine((token)->location.start.line); \
-        error.setColumn((token)->location.start.column); \
+        error.setLine(line); \
+        error.setColumn(column); \
         error.setDescription(desc.trimmed()); \
         exceptions << error; \
         return false; \
     }
 
+#define COMPILE_EXCEPTION(token, desc) \
+    COMPILE_EXCEPTION_LOCATION((token)->location.start.line, (token)->location.start.column, desc)
+
 /*!
     \macro COMPILE_CHECK
     \internal
@@ -2641,16 +2643,25 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeScript::Object *obj)
         if (propNames.testAndSet(prop.name.hash())) {
             for (Object::DynamicProperty *p2 = obj->dynamicProperties.first(); p2 != p; 
                  p2 = obj->dynamicProperties.next(p2)) {
-                if (p2->name == prop.name)
-                    COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
+                if (p2->name == prop.name) {
+                    COMPILE_EXCEPTION_LOCATION(prop.nameLocation.line,
+                                               prop.nameLocation.column,
+                                               tr("Duplicate property name"));
+                }
             }
         }
 
-        if (prop.name.at(0).isUpper())
-            COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
+        if (prop.name.at(0).isUpper()) {
+            COMPILE_EXCEPTION_LOCATION(prop.nameLocation.line,
+                                       prop.nameLocation.column,
+                                       tr("Property names cannot begin with an upper case letter"));
+        }
 
-        if (enginePrivate->v8engine()->illegalNames().contains(prop.name))
-            COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
+        if (enginePrivate->v8engine()->illegalNames().contains(prop.name)) {
+            COMPILE_EXCEPTION_LOCATION(prop.nameLocation.line,
+                                       prop.nameLocation.column,
+                                       tr("Illegal property name"));
+        }
     }
 
     for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
index 1a60893..cbb2bc2 100644 (file)
@@ -1032,6 +1032,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
         property->isDefaultProperty = node->isDefaultMember;
         property->isReadOnly = node->isReadonlyMember;
         property->type = type;
+        property->nameLocation.line = node->identifierToken.startLine;
+        property->nameLocation.column = node->identifierToken.startColumn;
         if (type >= Object::DynamicProperty::Custom) {
             QDeclarativeScript::TypeReference *typeRef =
                 _parser->findOrCreateType(memberType.toString());
@@ -1218,7 +1220,7 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
     if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) {
 
         Object::DynamicSlot *slot = _parser->_pool.New<Object::DynamicSlot>();
-        slot->location = location(funDecl->firstSourceLocation(), funDecl->lastSourceLocation());
+        slot->location = location(funDecl->identifierToken, funDecl->lastSourceLocation());
 
         AST::FormalParameterList *f = funDecl->formals;
         while (f) {
index 79b08b6..4063c3b 100644 (file)
@@ -401,6 +401,7 @@ public:
         QHashedStringRef name;
         QDeclarativeScript::Property *defaultValue;
         LocationSpan location;
+        Location nameLocation;
 
         // Used by Object::DynamicPropertyList
         DynamicProperty *nextProperty;
index fa13e69..6a03af5 100644 (file)
@@ -429,7 +429,7 @@ void tst_qdeclarativeqt::createQmlObject()
 
     QString warning1 = component.url().toString() + ":7: Error: Qt.createQmlObject(): Invalid arguments";
     QString warning2 = component.url().toString()+ ":10: Error: Qt.createQmlObject(): failed to create object: \n    " + testFileUrl("inline").toString() + ":2:10: Blah is not a type";
-    QString warning3 = component.url().toString()+ ":11: Error: Qt.createQmlObject(): failed to create object: \n    " + testFileUrl("main.qml").toString() + ":4:1: Duplicate property name";
+    QString warning3 = component.url().toString()+ ":11: Error: Qt.createQmlObject(): failed to create object: \n    " + testFileUrl("main.qml").toString() + ":4:14: Duplicate property name";
     QString warning4 = component.url().toString()+ ":9: Error: Qt.createQmlObject(): Missing parent object";
     QString warning5 = component.url().toString()+ ":8: Error: Qt.createQmlObject(): Invalid arguments";
     QString warning6 = "RunTimeError:  Qt.createQmlObject(): failed to create object: \n    " + testFileUrl("inline").toString() + ":3: Cannot assign object type QObject with no default method";