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