From 2ce1592a14b2d7ac8eb1c4dc2beac597277adb74 Mon Sep 17 00:00:00 2001
From: Christian Kamm <christian.d.kamm@nokia.com>
Date: Thu, 18 Feb 2010 14:21:53 +0100
Subject: [PATCH] Error when binding to nonexistant member of property in Qml.

This now errors for:
anchors.undefinedAnchor: foo
x.undefinedAnchor
---
 src/libs/qmljs/qmljscheck.cpp | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 719ac8bd2f4..39ab69fd04f 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -174,7 +174,7 @@ bool Check::visit(UiArrayBinding *ast)
     return true;
 }
 
-void Check::checkScopeObjectMember(const AST::UiQualifiedId *id)
+void Check::checkScopeObjectMember(const UiQualifiedId *id)
 {
     if (_allowAnyProperty)
         return;
@@ -184,7 +184,7 @@ void Check::checkScopeObjectMember(const AST::UiQualifiedId *id)
     if (! id)
         return; // ### error?
 
-    const QString propertyName = id->name->asString();
+    QString propertyName = id->name->asString();
 
     if (propertyName == QLatin1String("id") && ! id->next)
         return;
@@ -196,15 +196,36 @@ void Check::checkScopeObjectMember(const AST::UiQualifiedId *id)
     if (! scopeObject)
         return;
 
+    // global lookup for first part of id
     const Value *value = scopeObject->lookupMember(propertyName, &_context);
     if (_extraScope && !value)
         value = _extraScope->lookupMember(propertyName, &_context);
     if (!value) {
         error(id->identifierToken,
               QString("'%1' is not a valid property name").arg(propertyName));
+        return;
     }
 
-    // ### check for rest of qualifiedId
+    // member lookup
+    const UiQualifiedId *idPart = id;
+    while (idPart->next) {
+        const ObjectValue *objectValue = value_cast<const ObjectValue *>(value);
+        if (! objectValue) {
+            error(idPart->identifierToken,
+                  QString("'%1' does not have members").arg(propertyName));
+            return;
+        }
+
+        idPart = idPart->next;
+        propertyName = idPart->name->asString();
+
+        value = objectValue->lookupMember(propertyName, &_context);
+        if (! value) {
+            error(idPart->identifierToken,
+                  QString("'%1' is not a member of '%2'").arg(propertyName, objectValue->className()));
+            return;
+        }
+    }
 }
 
 void Check::error(const AST::SourceLocation &loc, const QString &message)
-- 
GitLab