Commit b82bc0b8 authored by Milian Wolff's avatar Milian Wolff

Actually ues the UseBuilder and clean up its code and fix bugs.

- our context builder did not properly map contexts nor did it
honor the isCompilingContexts flag - required for UseBuilder
- the Editor stuff is ugly but we only need it to make the
AbstractUseBuilder happy so inline it for now and mark for deletion
once I have more time
- similarily we need to pass around the AstNode <-> Context mapping
for the UseBuilder manually for now, that should be cleaned up
and be put into the ParseSession.
parent a08a7098
kde4_add_library(kdevqmljsduchain SHARED
helper.cpp
parsesession.cpp
editorintegrator.cpp
debugvisitor.cpp
contextbuilder.cpp
declarationbuilder.cpp
......
......@@ -19,13 +19,15 @@
#include "contextbuilder.h"
#include "parsesession.h"
using namespace KDevelop;
ContextBuilder::ContextBuilder()
: ContextBuilderBase()
, m_session()
, m_editor(0)
, m_session(0)
, m_mapAst(false)
, m_editor(new Editor(&m_session))
{
}
......@@ -34,16 +36,6 @@ RangeInRevision ContextBuilder::editorFindRange(QmlJS::AST::Node* fromNode, QmlJ
return m_session->editorFindRange(fromNode, toNode);
}
void ContextBuilder::setEditor(EditorIntegrator *editor)
{
m_editor = editor;
}
EditorIntegrator* ContextBuilder::editor() const
{
return m_editor;
}
QualifiedIdentifier ContextBuilder::identifierForNode(QmlJS::AST::IdentifierPropertyName* node)
{
return QualifiedIdentifier(node->id.toString());
......@@ -85,13 +77,13 @@ bool ContextBuilder::visit(QmlJS::AST::FunctionDeclaration* node)
const RangeInRevision pRange(m_session->locationToRange(node->lparenToken).end,
m_session->locationToRange(node->rparenToken).start);
DUContext* parameters = openContextInternal(pRange, DUContext::Function, functionName);
DUContext* parameters = openContext(node, pRange, DUContext::Function, functionName);
visit(node->formals);
closeContext();
const RangeInRevision bRange(m_session->locationToRange(node->lbraceToken).end,
m_session->locationToRange(node->rbraceToken).start);
DUContext* body = openContextInternal(bRange, DUContext::Other, functionName);
DUContext* body = openContext(node, bRange, DUContext::Other, functionName);
if (compilingContexts()) {
DUChainWriteLocker lock;
body->addImportedParentContext(parameters);
......@@ -102,3 +94,13 @@ bool ContextBuilder::visit(QmlJS::AST::FunctionDeclaration* node)
// return false, we visited the children manually
return false;
}
Editor* ContextBuilder::editor() const
{
return m_editor.data();
}
ContextBuilder::NodeToContextHash ContextBuilder::nodeToAstMapping() const
{
return m_astToContext;
}
......@@ -21,16 +21,32 @@
#define CONTEXTBUILDER_H
#include <language/duchain/builders/abstractcontextbuilder.h>
#include <qmljs/parser/qmljsast_p.h>
#include <qmljs/qmljsdocument.h>
#include "editorintegrator.h"
#include "duchainexport.h"
class ParseSession;
class EditorIntegrator;
typedef KDevelop::AbstractContextBuilder<QmlJS::AST::Node, QmlJS::AST::IdentifierPropertyName> ContextBuilderBase;
///TODO: cleanup KDevplatform API, remove need for editor integrator
class Editor
{
public:
Editor(ParseSession** session)
: m_session(session)
{}
ParseSession* parseSession() const
{
return *m_session;
}
private:
ParseSession** m_session;
};
class KDEVQMLJSDUCHAIN_EXPORT ContextBuilder : public ContextBuilderBase, public QmlJS::AST::Visitor
{
public:
......@@ -48,17 +64,19 @@ public:
void setParseSession(ParseSession* session);
void setEditor(EditorIntegrator *editor);
EditorIntegrator* editor() const;
using Visitor::visit;
virtual bool visit(QmlJS::AST::FunctionDeclaration* node);
Editor* editor() const;
typedef QHash<QmlJS::AST::Node*, KDevelop::DUContext*> NodeToContextHash;
NodeToContextHash nodeToAstMapping() const;
protected:
ParseSession* m_session;
EditorIntegrator* m_editor;
QHash<QmlJS::AST::Node*, KDevelop::DUContext*> m_astToContext;
NodeToContextHash m_astToContext;
bool m_mapAst; // make KDevelop::AbstractContextBuilder happy
QScopedPointer<Editor> m_editor; // make KDevelop::AbstractUseBuilder happy
};
......
/*************************************************************************************
* Copyright (C) 2013 by Andrea Scarpino <andrea@archlinux.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
*************************************************************************************/
#include "editorintegrator.h"
EditorIntegrator::EditorIntegrator()
{
}
void EditorIntegrator::setParseSession(ParseSession *session)
{
m_session = session;
}
ParseSession* EditorIntegrator::parseSession() const
{
return m_session;
}
/*************************************************************************************
* Copyright (C) 2013 by Andrea Scarpino <andrea@archlinux.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
*************************************************************************************/
#ifndef QMLJSEDITORINTEGRATOR_H
#define QMLJSEDITORINTEGRATOR_H
#include "parsesession.h"
class KDEVQMLJSDUCHAIN_EXPORT EditorIntegrator
{
public:
EditorIntegrator();
void setParseSession(ParseSession *session);
ParseSession* parseSession() const;
private:
ParseSession* m_session;
};
#endif // QMLJSEDITORINTEGRATOR_H
\ No newline at end of file
......@@ -27,8 +27,11 @@ using namespace KDevelop;
DeclarationPointer getDeclaration(const QualifiedIdentifier& id, const DUContextPointer& context)
{
foreach(Declaration* dec, context->findDeclarations(id)) {
return DeclarationPointer(dec);
DUChainReadLocker lock;
if (context) {
foreach(Declaration* dec, context->findDeclarations(id)) {
return DeclarationPointer(dec);
}
}
return DeclarationPointer();
}
......
......@@ -19,20 +19,22 @@
#include "usebuilder.h"
#include "helper.h"
#include "parsesession.h"
using namespace KDevelop;
UseBuilder::UseBuilder()
UseBuilder::UseBuilder(ParseSession* session, const ContextBuilder::NodeToContextHash& mapping)
: UseBuilderBase()
{
m_session = session;
m_astToContext = mapping;
}
bool UseBuilder::visit(QmlJS::AST::IdentifierExpression* node)
{
const RangeInRevision range(m_session->locationToRange(node->identifierToken));
const QualifiedIdentifier id(node->name.toString());
const DeclarationPointer decl(QmlJS::getDeclaration(id, range, DUContextPointer(topContext())));
const DeclarationPointer decl(QmlJS::getDeclaration(id, DUContextPointer(topContext())));
newUse(node, range, decl);
const bool ret = UseBuilderBase::visit(node);
......
......@@ -28,12 +28,12 @@ typedef KDevelop::AbstractUseBuilder<QmlJS::AST::Node, QmlJS::AST::IdentifierPro
class KDEVQMLJSDUCHAIN_EXPORT UseBuilder : public UseBuilderBase
{
public:
UseBuilder();
///TODO: cleanup manual passing of mapping, push into parse session
UseBuilder(ParseSession* session, const ContextBuilder::NodeToContextHash& mapping);
protected:
using Visitor::visit;
virtual bool visit(QmlJS::AST::IdentifierExpression* node);
};
#endif // USEBUILDER_H
......@@ -29,6 +29,7 @@
#include "duchain/declarationbuilder.h"
#include "duchain/parsesession.h"
#include "duchain/usebuilder.h"
#include "debug.h"
......@@ -67,6 +68,7 @@ void QmlJsParseJob::run()
context = DUChainUtils::standardContextForUrl(document().toUrl());
}
ContextBuilder::NodeToContextHash mapping;
if (session.ast()) {
QReadLocker parseLock(languageSupport()->language()->parseLock());
......@@ -76,6 +78,7 @@ void QmlJsParseJob::run()
DeclarationBuilder builder(&session);
context = builder.build(document(), session.ast(), context);
mapping = builder.nodeToAstMapping();
}
if (abortRequested()) {
......@@ -88,6 +91,10 @@ void QmlJsParseJob::run()
file->setLanguage(ParseSession::languageString());
context = new TopDUContext(document(), RangeInRevision(0, 0, INT_MAX, INT_MAX), file);
DUChain::self()->addDocumentChain(context);
} else if ( minimumFeatures() & TopDUContext::AllDeclarationsContextsAndUses ) {
// build uses
UseBuilder useBuilder(&session, mapping);
useBuilder.buildUses(session.ast());
}
setDuChain(context);
......
Markdown is supported
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