QmlJS: Set importing scopes for scripts correctly.

They had not yet been updated to the new way of importing javascript.

Reviewed-by: Erik Verbruggen
This commit is contained in:
Christian Kamm
2010-04-22 16:32:28 +02:00
parent 3286f48504
commit 3096b2a06f
4 changed files with 30 additions and 72 deletions

View File

@@ -54,16 +54,16 @@ Bind::~Bind()
{ {
} }
QStringList Bind::includedScripts() const
{
return _includedScripts;
}
QStringList Bind::fileImports() const QStringList Bind::fileImports() const
{ {
return _fileImports; return _fileImports;
} }
QStringList Bind::directoryImports() const
{
return _directoryImports;
}
QStringList Bind::libraryImports() const QStringList Bind::libraryImports() const
{ {
return _libraryImports; return _libraryImports;
@@ -142,47 +142,11 @@ ExpressionNode *Bind::expression(UiScriptBinding *ast) const
return 0; return 0;
} }
void Bind::processScript(AST::UiQualifiedId *qualifiedId, AST::UiObjectInitializer *initializer)
{
Q_UNUSED(qualifiedId);
if (! initializer)
return;
for (UiObjectMemberList *it = initializer->members; it; it = it->next) {
if (UiScriptBinding *binding = cast<UiScriptBinding *>(it->member)) {
const QString bindingName = toString(binding->qualifiedId);
if (bindingName == QLatin1String("source")) {
if (StringLiteral *literal = cast<StringLiteral *>(expression(binding))) {
QFileInfo fileInfo(QDir(_doc->path()), literal->value->asString());
const QString scriptPath = fileInfo.absoluteFilePath();
_includedScripts.append(scriptPath);
}
}
} else if (UiSourceElement *binding = cast<UiSourceElement *>(it->member)) {
if (FunctionDeclaration *decl = cast<FunctionDeclaration *>(binding->sourceElement)) {
accept(decl); // process the function declaration
} else {
// ### unexpected source element
}
} else {
// ### unexpected binding.
}
}
}
ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitializer *initializer) ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitializer *initializer)
{ {
ObjectValue *parentObjectValue = 0; ObjectValue *parentObjectValue = 0;
const QString typeName = toString(qualifiedTypeNameId); const QString typeName = toString(qualifiedTypeNameId);
if (typeName == QLatin1String("Script")) {
// Script blocks all contribute to the same scope
parentObjectValue = switchObjectValue(_functionEnvironment);
processScript(qualifiedTypeNameId, initializer);
switchObjectValue(parentObjectValue);
}
// normal component instance // normal component instance
ASTObjectValue *objectValue = new ASTObjectValue(qualifiedTypeNameId, initializer, _doc, &_engine); ASTObjectValue *objectValue = new ASTObjectValue(qualifiedTypeNameId, initializer, _doc, &_engine);
QmlPrototypeReference *prototypeReference = QmlPrototypeReference *prototypeReference =
@@ -225,7 +189,13 @@ bool Bind::visit(UiImport *ast)
if (ast->importUri) { if (ast->importUri) {
_libraryImports += toString(ast->importUri, QLatin1Char('/')); _libraryImports += toString(ast->importUri, QLatin1Char('/'));
} else if (ast->fileName) { } else if (ast->fileName) {
_fileImports += ast->fileName->asString(); const QFileInfo importFileInfo(_doc->path() + QLatin1Char('/') + ast->fileName->asString());
if (importFileInfo.isFile())
_fileImports += importFileInfo.absoluteFilePath();
else if (importFileInfo.isDir())
_directoryImports += importFileInfo.absoluteFilePath();
//else
// error: file or directory does not exist
} }
return false; return false;

View File

@@ -50,8 +50,8 @@ public:
Bind(Document *doc); Bind(Document *doc);
virtual ~Bind(); virtual ~Bind();
QStringList includedScripts() const;
QStringList fileImports() const; QStringList fileImports() const;
QStringList directoryImports() const;
QStringList libraryImports() const; QStringList libraryImports() const;
Interpreter::ObjectValue *currentObjectValue() const; Interpreter::ObjectValue *currentObjectValue() const;
@@ -91,7 +91,6 @@ protected:
Interpreter::ObjectValue *bindObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer); Interpreter::ObjectValue *bindObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer);
AST::ExpressionNode *expression(AST::UiScriptBinding *ast) const; AST::ExpressionNode *expression(AST::UiScriptBinding *ast) const;
void processScript(AST::UiQualifiedId *qualifiedId, AST::UiObjectInitializer *initializer);
private: private:
Document *_doc; Document *_doc;
@@ -107,6 +106,7 @@ private:
QStringList _includedScripts; QStringList _includedScripts;
QStringList _fileImports; QStringList _fileImports;
QStringList _directoryImports;
QStringList _libraryImports; QStringList _libraryImports;
}; };

View File

@@ -64,14 +64,15 @@ void Link::initializeScopeChain()
if (const ObjectValue *typeEnvironment = _context->typeEnvironment(_doc.data())) if (const ObjectValue *typeEnvironment = _context->typeEnvironment(_doc.data()))
scopeChain.qmlTypes = typeEnvironment; scopeChain.qmlTypes = typeEnvironment;
} else { } else {
// add scope chains for all components that source this document // add scope chains for all components that import this file
// ### TODO: This needs updates for the new way of importing scripts
foreach (Document::Ptr otherDoc, _snapshot) { foreach (Document::Ptr otherDoc, _snapshot) {
if (otherDoc->bind()->includedScripts().contains(_doc->fileName())) { foreach (const QString &fileImport, otherDoc->bind()->fileImports()) {
ScopeChain::QmlComponentChain *component = new ScopeChain::QmlComponentChain; if (_doc->fileName() == fileImport) {
componentScopes.insert(otherDoc.data(), component); ScopeChain::QmlComponentChain *component = new ScopeChain::QmlComponentChain;
scopeChain.qmlComponentScope.instantiatingComponents += component; componentScopes.insert(otherDoc.data(), component);
makeComponentChain(otherDoc, component, &componentScopes); scopeChain.qmlComponentScope.instantiatingComponents += component;
makeComponentChain(otherDoc, component, &componentScopes);
}
} }
} }
@@ -114,16 +115,6 @@ void Link::makeComponentChain(
if (bind->rootObjectValue()) if (bind->rootObjectValue())
target->rootObject = bind->rootObjectValue(); target->rootObject = bind->rootObjectValue();
const QStringList &includedScripts = bind->includedScripts();
for (int index = includedScripts.size() - 1; index != -1; --index) {
const QString &scriptFile = includedScripts.at(index);
if (Document::Ptr scriptDoc = _snapshot.document(scriptFile)) {
if (scriptDoc->jsProgram())
target->functionScopes += scriptDoc->bind()->rootObjectValue();
}
}
target->functionScopes += bind->functionEnvironment(); target->functionScopes += bind->functionEnvironment();
target->ids = bind->idEnvironment(); target->ids = bind->idEnvironment();
} }

View File

@@ -227,17 +227,14 @@ static void findNewFileImports(const Document::Ptr &doc, const Snapshot &snapsho
{ {
// scan files and directories that are explicitly imported // scan files and directories that are explicitly imported
foreach (const QString &fileImport, doc->bind()->fileImports()) { foreach (const QString &fileImport, doc->bind()->fileImports()) {
const QFileInfo importFileInfo(doc->path() + QLatin1Char('/') + fileImport); if (! snapshot.document(fileImport))
const QString &importFilePath = importFileInfo.absoluteFilePath(); *importedFiles += fileImport;
if (importFileInfo.isFile()) { }
if (! snapshot.document(importFilePath)) foreach (const QString &directoryImport, doc->bind()->directoryImports()) {
*importedFiles += importFilePath; if (snapshot.documentsInDirectory(directoryImport).isEmpty()) {
} else if (importFileInfo.isDir()) { if (! scannedPaths->contains(directoryImport)) {
if (snapshot.documentsInDirectory(importFilePath).isEmpty()) { *importedFiles += qmlFilesInDirectory(directoryImport);
if (! scannedPaths->contains(importFilePath)) { scannedPaths->insert(directoryImport);
*importedFiles += qmlFilesInDirectory(importFilePath);
scannedPaths->insert(importFilePath);
}
} }
} }
} }