From 124358d25804c474b8c68405193dec59b335df46 Mon Sep 17 00:00:00 2001
From: Christian Kamm <christian.d.kamm@nokia.com>
Date: Wed, 24 Nov 2010 15:12:11 +0100
Subject: [PATCH] QmlJS: Enhance check pass to do lookup... and disable it.

It still generates too many false-negatives for now. Will be enabled
once the remaining lookup failures have been fixed.

Reviewed-by: Erik Verbruggen
---
 src/libs/qmljs/qmljscheck.cpp | 58 +++++++++++++++++++++++++++++++++++
 src/libs/qmljs/qmljscheck.h   |  6 ++++
 2 files changed, 64 insertions(+)

diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 3cbe72b94b2..9ac19d8ed08 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -197,6 +197,7 @@ Check::Check(Document::Ptr doc, const Snapshot &snapshot, const Context *linkedC
     , _context(*linkedContextNoScope)
     , _scopeBuilder(&_context, doc, snapshot)
     , _ignoreTypeErrors(false)
+    , _lastValue(0)
 {
 }
 
@@ -321,6 +322,63 @@ bool Check::visit(UiArrayBinding *ast)
     return true;
 }
 
+bool Check::visit(IdentifierExpression *ast)
+{
+    // currently disabled: too many false negatives
+    return true;
+
+    _lastValue = 0;
+    if (ast->name) {
+        Evaluate evaluator(&_context);
+        _lastValue = evaluator.reference(ast);
+        if (!_lastValue)
+            error(ast->identifierToken, tr("unknown identifier"));
+        if (const Reference *ref = value_cast<const Reference *>(_lastValue)) {
+            _lastValue = _context.lookupReference(ref);
+            if (!_lastValue)
+                error(ast->identifierToken, tr("could not resolve"));
+        }
+    }
+    return false;
+}
+
+bool Check::visit(FieldMemberExpression *ast)
+{
+    // currently disabled: too many false negatives
+    return true;
+
+    Node::accept(ast->base, this);
+    if (!_lastValue)
+        return false;
+    const ObjectValue *obj = _lastValue->asObjectValue();
+    if (!obj) {
+        error(locationFromRange(ast->base->firstSourceLocation(), ast->base->lastSourceLocation()),
+              tr("does not have members"));
+    }
+    if (!obj || !ast->name) {
+        _lastValue = 0;
+        return false;
+    }
+    _lastValue = obj->lookupMember(ast->name->asString(), &_context);
+    if (!_lastValue)
+        error(ast->identifierToken, tr("unknown member"));
+    return false;
+}
+
+bool Check::visit(FunctionDeclaration *ast)
+{
+    return visit(static_cast<FunctionExpression *>(ast));
+}
+
+bool Check::visit(FunctionExpression *ast)
+{
+    Node::accept(ast->formals, this);
+    _scopeBuilder.push(ast);
+    Node::accept(ast->body, this);
+    _scopeBuilder.pop();
+    return false;
+}
+
 /// When something is changed here, also change ReadingContext::lookupProperty in
 /// texttomodelmerger.cpp
 /// ### Maybe put this into the context as a helper method.
diff --git a/src/libs/qmljs/qmljscheck.h b/src/libs/qmljs/qmljscheck.h
index 049b197e5f9..97297eac357 100644
--- a/src/libs/qmljs/qmljscheck.h
+++ b/src/libs/qmljs/qmljscheck.h
@@ -56,6 +56,10 @@ protected:
     virtual bool visit(AST::UiObjectBinding *ast);
     virtual bool visit(AST::UiScriptBinding *ast);
     virtual bool visit(AST::UiArrayBinding *ast);
+    virtual bool visit(AST::IdentifierExpression *ast);
+    virtual bool visit(AST::FieldMemberExpression *ast);
+    virtual bool visit(AST::FunctionDeclaration *ast);
+    virtual bool visit(AST::FunctionExpression *ast);
 
 private:
     void visitQmlObject(AST::Node *ast, AST::UiQualifiedId *typeId,
@@ -74,6 +78,8 @@ private:
     QList<DiagnosticMessage> _messages;
 
     bool _ignoreTypeErrors;
+
+    const Interpreter::Value *_lastValue;
 };
 
 QMLJS_EXPORT QColor toQColor(const QString &qmlColorString);
-- 
GitLab