forked from qt-creator/qt-creator
Pass in the whole AST path for scope creation.
Just the declaring member isn't enough.
This commit is contained in:
@@ -76,11 +76,10 @@ QList<DiagnosticMessage> Check::operator()()
|
||||
return _messages;
|
||||
}
|
||||
|
||||
bool Check::visit(UiProgram *ast)
|
||||
bool Check::visit(UiProgram *)
|
||||
{
|
||||
// build the initial scope chain
|
||||
if (ast->members && ast->members->member)
|
||||
_link.scopeChainAt(_doc, ast->members->member);
|
||||
_link.scopeChainAt(_doc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -776,10 +776,10 @@ Context::~Context()
|
||||
{
|
||||
}
|
||||
|
||||
void Context::build(Node *node, QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot)
|
||||
void Context::build(const QList<AST::Node *> &astPath, Document::Ptr doc, const Snapshot &snapshot)
|
||||
{
|
||||
Link link(this, doc, snapshot);
|
||||
link.scopeChainAt(doc, node);
|
||||
link.scopeChainAt(doc, astPath);
|
||||
}
|
||||
|
||||
Engine *Context::engine() const
|
||||
|
||||
@@ -264,7 +264,7 @@ public:
|
||||
Context(Engine *engine);
|
||||
~Context();
|
||||
|
||||
void build(AST::Node *node, const Document::Ptr doc, const Snapshot &snapshot);
|
||||
void build(const QList<AST::Node *> &astPath, const Document::Ptr doc, const Snapshot &snapshot);
|
||||
|
||||
Engine *engine() const;
|
||||
const ScopeChain &scopeChain() const;
|
||||
|
||||
@@ -29,38 +29,52 @@ Interpreter::Engine *Link::engine()
|
||||
return _context->engine();
|
||||
}
|
||||
|
||||
void Link::scopeChainAt(Document::Ptr doc, Node *currentObject)
|
||||
void Link::scopeChainAt(Document::Ptr doc, const QList<Node *> &astPath)
|
||||
{
|
||||
ScopeChain &scopeChain = _context->scopeChain();
|
||||
|
||||
// ### TODO: This object ought to contain the global namespace additions by QML.
|
||||
scopeChain.globalScope = engine()->globalObject();
|
||||
|
||||
if (! doc)
|
||||
if (! doc) {
|
||||
scopeChain.update();
|
||||
return;
|
||||
}
|
||||
|
||||
Bind *bind = doc->bind();
|
||||
QHash<Document *, ScopeChain::QmlComponentChain *> componentScopes;
|
||||
|
||||
int qmlScopeObjectIndex = -1;
|
||||
|
||||
if (doc->qmlProgram()) {
|
||||
_context->setLookupMode(Context::QmlLookup);
|
||||
|
||||
makeComponentChain(doc, &scopeChain.qmlComponentScope, &componentScopes);
|
||||
|
||||
ObjectValue *scopeObject = 0;
|
||||
if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(currentObject))
|
||||
scopeObject = bind->findQmlObject(definition);
|
||||
else if (UiObjectBinding *binding = cast<UiObjectBinding *>(currentObject))
|
||||
scopeObject = bind->findQmlObject(binding);
|
||||
// find the last object definition or object binding: that is the scope object
|
||||
for (int i = astPath.size() - 1; i >= 0; --i) {
|
||||
Node *node = astPath.at(i);
|
||||
|
||||
if (scopeObject && scopeObject != scopeChain.qmlComponentScope.rootObject)
|
||||
scopeChain.qmlScopeObjects += scopeObject;
|
||||
ObjectValue *scopeObject = 0;
|
||||
if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(node))
|
||||
scopeObject = bind->findQmlObject(definition);
|
||||
else if (UiObjectBinding *binding = cast<UiObjectBinding *>(node))
|
||||
scopeObject = bind->findQmlObject(binding);
|
||||
|
||||
if (scopeObject) {
|
||||
if (scopeObject != scopeChain.qmlComponentScope.rootObject)
|
||||
scopeChain.qmlScopeObjects += scopeObject;
|
||||
qmlScopeObjectIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (const ObjectValue *typeEnvironment = _context->typeEnvironment(doc.data()))
|
||||
scopeChain.qmlTypes = typeEnvironment;
|
||||
} else {
|
||||
// the global scope of a js file does not see the instantiating component
|
||||
if (currentObject != 0) {
|
||||
qDebug() << "ast path length: " << astPath.size();
|
||||
if (astPath.size() != 0) {
|
||||
// add scope chains for all components that source this document
|
||||
foreach (Document::Ptr otherDoc, _docs) {
|
||||
if (otherDoc->bind()->includedScripts().contains(doc->fileName())) {
|
||||
@@ -77,13 +91,17 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject)
|
||||
scopeChain.jsScopes += bind->rootObjectValue();
|
||||
}
|
||||
|
||||
if (FunctionDeclaration *fun = cast<FunctionDeclaration *>(currentObject)) {
|
||||
ObjectValue *activation = engine()->newObject(/*prototype = */ 0);
|
||||
for (FormalParameterList *it = fun->formals; it; it = it->next) {
|
||||
if (it->name)
|
||||
activation->setProperty(it->name->asString(), engine()->undefinedValue());
|
||||
for (int i = qmlScopeObjectIndex + 1; i < astPath.size(); ++i) {
|
||||
Node *node = astPath.at(i);
|
||||
|
||||
if (FunctionDeclaration *fun = cast<FunctionDeclaration *>(node)) {
|
||||
ObjectValue *activation = engine()->newObject(/*prototype = */ 0);
|
||||
for (FormalParameterList *it = fun->formals; it; it = it->next) {
|
||||
if (it->name)
|
||||
activation->setProperty(it->name->asString(), engine()->undefinedValue());
|
||||
}
|
||||
scopeChain.jsScopes += activation;
|
||||
}
|
||||
scopeChain.jsScopes += activation;
|
||||
}
|
||||
|
||||
scopeChain.update();
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
~Link();
|
||||
|
||||
// Get the scope chain for the currentObject inside doc.
|
||||
void scopeChainAt(Document::Ptr doc, AST::Node *currentObject);
|
||||
void scopeChainAt(Document::Ptr doc, const QList<AST::Node *> &astPath = QList<AST::Node *>());
|
||||
|
||||
private:
|
||||
Interpreter::Engine *engine();
|
||||
|
||||
Reference in New Issue
Block a user