Commit 7e40fe16 authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

Switched navigation over to the new and shiny QmlLookupContext &

friends.
parent 380812d8
......@@ -721,8 +721,6 @@ TextEditor::BaseTextEditor::Link ScriptEditor::findLinkAt(const QTextCursor &cur
QmlResolveExpression resolve(context);
QmlSymbol *symbol = resolve(expressionUnderCursor.expressionNode());
qDebug() << "*** Searching for node" << expressionUnderCursor.expressionNode() << "returned symbol" << symbol;
if (!symbol)
return link;
......@@ -732,6 +730,8 @@ TextEditor::BaseTextEditor::Link ScriptEditor::findLinkAt(const QTextCursor &cur
link.fileName = target->fileName();
link.line = target->line();
link.column = target->column();
if (link.column > 0)
--link.column;
}
return link;
......
......@@ -65,9 +65,14 @@ bool QmlExpressionUnderCursor::visit(QmlJS::AST::IdentifierExpression *ast)
bool QmlExpressionUnderCursor::visit(QmlJS::AST::UiObjectBinding *ast)
{
Node::accept(ast->qualifiedId, this);
Node::accept(ast->qualifiedTypeNameId, this);
_scopes.push(ast);
return true;
Node::accept(ast->initializer, this);
return false;
}
void QmlExpressionUnderCursor::endVisit(QmlJS::AST::UiObjectBinding *)
......@@ -77,12 +82,43 @@ void QmlExpressionUnderCursor::endVisit(QmlJS::AST::UiObjectBinding *)
bool QmlExpressionUnderCursor::visit(QmlJS::AST::UiObjectDefinition *ast)
{
Node::accept(ast->qualifiedTypeNameId, this);
_scopes.push(ast);
return true;
Node::accept(ast->initializer, this);
return false;
}
void QmlExpressionUnderCursor::endVisit(QmlJS::AST::UiObjectDefinition *)
{
_scopes.pop();
}
bool QmlExpressionUnderCursor::visit(QmlJS::AST::UiQualifiedId *ast)
{
if (ast->identifierToken.offset <= _pos) {
for (UiQualifiedId *iter = ast; iter; iter = iter->next) {
if (_pos <= iter->identifierToken.end()) {
// found it
_expressionNode = ast;
_expressionOffset = ast->identifierToken.offset;
for (UiQualifiedId *iter2 = ast; iter2; iter2 = iter2->next) {
_expressionLength = iter2->identifierToken.end() - _expressionOffset;
}
_expressionScopes = _scopes;
break;
}
}
}
return false;
}
bool QmlExpressionUnderCursor::visit(QmlJS::AST::UiImport * /*ast*/)
{
return false;
}
......@@ -32,8 +32,10 @@ protected:
virtual bool visit(QmlJS::AST::Block *ast);
virtual bool visit(QmlJS::AST::FieldMemberExpression *ast);
virtual bool visit(QmlJS::AST::IdentifierExpression *ast);
virtual bool visit(QmlJS::AST::UiImport *ast);
virtual bool visit(QmlJS::AST::UiObjectBinding *ast);
virtual bool visit(QmlJS::AST::UiObjectDefinition *ast);
virtual bool visit(QmlJS::AST::UiQualifiedId *ast);
virtual void endVisit(QmlJS::AST::Block *);
virtual void endVisit(QmlJS::AST::UiObjectBinding *);
......
......@@ -19,9 +19,26 @@ QmlLookupContext::QmlLookupContext(const QStack<QmlJS::AST::Node *> &scopes,
{
}
QmlSymbol *QmlLookupContext::resolve(const QString &name) const
QmlLookupContext::~QmlLookupContext()
{
qDeleteAll(_temporarySymbols);
}
QmlSymbol *QmlLookupContext::resolve(const QString &name)
{
// ### TODO: look at property definitions
if (name == "parent") {
for (int i = _scopes.size() - 2; i >= 0; --i) {
Node *scope = _scopes.at(i);
if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(scope))
return createSymbol(_doc->fileName(), definition);
else if (UiObjectBinding *binding = cast<UiObjectBinding*>(scope))
return createSymbol(_doc->fileName(), binding);
}
return 0;
}
// look at the ids.
const DuiDocument::IdTable ids = _doc->ids();
......@@ -31,3 +48,43 @@ QmlSymbol *QmlLookupContext::resolve(const QString &name) const
else
return 0;
}
QmlSymbol *QmlLookupContext::createSymbol(const QString &fileName, QmlJS::AST::UiObjectMember *node)
{
QmlSymbol *symbol = new QmlSymbolFromFile(fileName, node);
_temporarySymbols.append(symbol);
return symbol;
}
QmlSymbol *QmlLookupContext::resolveType(const QString &name)
{
UiProgram *prog = _doc->program();
if (!prog)
return 0;
UiImportList *imports = prog->imports;
if (!imports)
return 0;
for (UiImportList *iter = imports; iter; iter = iter->next) {
UiImport *import = iter->import;
if (!import)
continue;
if (!(import->fileName))
continue;
const QString path = import->fileName->asString();
const QMap<QString, DuiDocument::Ptr> importedTypes = _snapshot.componentsDefinedByImportedDocuments(_doc, path);
if (importedTypes.contains(name)) {
DuiDocument::Ptr importedDoc = importedTypes.value(name);
UiProgram *importedProgram = importedDoc->program();
if (importedProgram && importedProgram->members && importedProgram->members->member)
return createSymbol(importedDoc->fileName(), importedProgram->members->member);
}
}
return 0;
}
......@@ -16,16 +16,22 @@ public:
QmlLookupContext(const QStack<QmlJS::AST::Node *> &scopes,
const DuiDocument::Ptr &doc,
const Snapshot &snapshot);
~QmlLookupContext();
QmlSymbol *resolve(const QString &name) const;
QmlSymbol *resolve(const QString &name);
QmlSymbol *resolveType(const QString &name);
DuiDocument::Ptr document() const
{ return _doc; }
private:
QmlSymbol *createSymbol(const QString &fileName, QmlJS::AST::UiObjectMember *node);
private:
QStack<QmlJS::AST::Node *> _scopes;
DuiDocument::Ptr _doc;
Snapshot _snapshot;
QList<QmlSymbol*> _temporarySymbols;
};
} // namespace Internal
......
......@@ -58,44 +58,49 @@ bool QmlResolveExpression::visit(FieldMemberExpression *ast)
{
const QString memberName = ast->name->asString();
if (QmlSymbol *base = typeOf(ast->base)) {
UiObjectMemberList *members = 0;
if (const QmlSymbolFromFile *symbol = base->asSymbolFromFile()) {
Node *node = symbol->node();
if (UiObjectBinding *binding = cast<UiObjectBinding*>(node)) {
if (binding->initializer)
members = binding->initializer->members;
} else if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(node)) {
if (definition->initializer)
members = binding->initializer->members;
}
const QmlSymbol *base = typeOf(ast->base);
if (!base)
return false;
if (base->isIdSymbol())
base = base->asIdSymbol()->parentNode();
UiObjectMemberList *members = 0;
if (const QmlSymbolFromFile *symbol = base->asSymbolFromFile()) {
Node *node = symbol->node();
if (UiObjectBinding *binding = cast<UiObjectBinding*>(node)) {
if (binding->initializer)
members = binding->initializer->members;
} else if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(node)) {
if (definition->initializer)
members = definition->initializer->members;
}
}
for (UiObjectMemberList *it = members; it; it = it->next) {
UiObjectMember *member = it->member;
for (UiObjectMemberList *it = members; it; it = it->next) {
UiObjectMember *member = it->member;
if (UiPublicMember *publicMember = cast<UiPublicMember *>(member)) {
if (publicMember->name && publicMember->name->asString() == memberName) {
_value = createPropertyDefinitionSymbol(publicMember);
break; // we're done.
}
} else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) {
if (matches(objectBinding->qualifiedId, memberName)) {
_value = createSymbolFromFile(objectBinding);
break; // we're done
}
} else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) {
if (matches(scriptBinding->qualifiedId, memberName)) {
_value = createSymbolFromFile(scriptBinding);
break; // we're done
}
} else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) {
if (matches(arrayBinding->qualifiedId, memberName)) {
_value = createSymbolFromFile(arrayBinding);
break; // we're done
}
if (UiPublicMember *publicMember = cast<UiPublicMember *>(member)) {
if (publicMember->name && publicMember->name->asString() == memberName) {
_value = createPropertyDefinitionSymbol(publicMember);
break; // we're done.
}
} else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) {
if (matches(objectBinding->qualifiedId, memberName)) {
_value = createSymbolFromFile(objectBinding);
break; // we're done
}
} else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) {
if (matches(scriptBinding->qualifiedId, memberName)) {
_value = createSymbolFromFile(scriptBinding);
break; // we're done
}
} else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) {
if (matches(arrayBinding->qualifiedId, memberName)) {
_value = createSymbolFromFile(arrayBinding);
break; // we're done
}
}
}
......@@ -103,6 +108,30 @@ bool QmlResolveExpression::visit(FieldMemberExpression *ast)
return false;
}
static inline QString toString(UiQualifiedId *id)
{
QString str;
for (UiQualifiedId *iter = id; iter; iter = iter->next) {
if (!(iter->name))
continue;
str.append(iter->name->asString());
if (iter->next)
str.append('.');
}
return str;
}
bool QmlResolveExpression::visit(QmlJS::AST::UiQualifiedId *ast)
{
_value = _context.resolveType(toString(ast));
return false;
}
QmlPropertyDefinitionSymbol *QmlResolveExpression::createPropertyDefinitionSymbol(QmlJS::AST::UiPublicMember *ast)
{
QmlPropertyDefinitionSymbol *symbol = new QmlPropertyDefinitionSymbol(_context.document()->fileName(), ast);
......
......@@ -23,8 +23,9 @@ protected:
QmlSymbol *typeOf(QmlJS::AST::Node *node);
QmlSymbol *switchValue(QmlSymbol *symbol);
virtual bool visit(QmlJS::AST::IdentifierExpression *ast);
virtual bool visit(QmlJS::AST::FieldMemberExpression *ast);
virtual bool visit(QmlJS::AST::IdentifierExpression *ast);
virtual bool visit(QmlJS::AST::UiQualifiedId *ast);
private:
QmlPropertyDefinitionSymbol *createPropertyDefinitionSymbol(QmlJS::AST::UiPublicMember *ast);
......
......@@ -15,12 +15,18 @@ bool QmlSymbol::isBuildInSymbol() const
bool QmlSymbol::isSymbolFromFile() const
{ return asSymbolFromFile() != 0; }
bool QmlSymbol::isIdSymbol() const
{ return asIdSymbol() != 0; }
QmlBuildInSymbol const *QmlSymbol::asBuildInSymbol() const
{ return 0; }
QmlSymbolFromFile const *QmlSymbol::asSymbolFromFile() const
{ return 0; }
QmlIdSymbol const *QmlSymbol::asIdSymbol() const
{ return 0; }
QmlBuildInSymbol::~QmlBuildInSymbol()
{}
......@@ -52,11 +58,14 @@ QmlIdSymbol::QmlIdSymbol(const QString &fileName, QmlJS::AST::UiScriptBinding *i
QmlIdSymbol::~QmlIdSymbol()
{}
QmlIdSymbol const *QmlIdSymbol::asIdSymbol() const
{ return this; }
int QmlIdSymbol::line() const
{ return idNode()->statement->firstSourceLocation().startLine; }
int QmlIdSymbol::column() const
{ return idNode()->statement->firstSourceLocation().startColumn - 1; }
{ return idNode()->statement->firstSourceLocation().startColumn; }
QmlJS::AST::UiScriptBinding *QmlIdSymbol::idNode() const
{ return cast<UiScriptBinding*>(node()); }
......
......@@ -14,9 +14,11 @@ public:
bool isBuildInSymbol() const;
bool isSymbolFromFile() const;
bool isIdSymbol() const;
virtual class QmlBuildInSymbol const *asBuildInSymbol() const;
virtual class QmlSymbolFromFile const *asSymbolFromFile() const;
virtual class QmlIdSymbol const *asIdSymbol() const;
};
class QmlBuildInSymbol: public QmlSymbol
......@@ -57,9 +59,14 @@ public:
QmlIdSymbol(const QString &fileName, QmlJS::AST::UiScriptBinding *idNode, const QmlSymbolFromFile &parentNode);
virtual ~QmlIdSymbol();
QmlIdSymbol const *asIdSymbol() const;
virtual int line() const;
virtual int column() const;
QmlSymbolFromFile const *parentNode() const
{ return &_parentNode; }
private:
QmlJS::AST::UiScriptBinding *idNode() const;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment